Выбор атрибута предка; "../ .." работает, "предок :: <tagname>" не работает - PullRequest
0 голосов
/ 03 ноября 2008

Я перебираю XML-документ, выбираю все элементы и создаю ссылки на основе предка, который обычно на два узла в дереве, но иногда на 3 или 4 узла. Для большинства элементов использование <xsl:value-of select="translate(../../@name,$uc,$lc)" /> работает просто отлично, но для случаев, когда предок имеет 3 или более узлов, я бы хотел использовать <xsl:value-of select="translate(ancestor::package/@name,$uc,$lc)" />, но это не работает.

Я использую xsltproc из Ruby для выполнения своих XSL-преобразований.

Пример дерева (да, в нем есть XSLT, нет, я не пытаюсь его обработать):

<package name="blork!" xmlns="http://xml.snapin.com/XBL">
  <xsl:template name="doSomething">
    <tokens>
      <token name="text-from-resource" export="public" />
    </tokens>
  </xsl:template>
</package>

XSL, который я использую:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s4="http://xml.snapin.com/XBL">
  <xsl:template match="/">
    <xsl:if test="count(//s4:token) >0">
      <xsl:text>Tokens!</xsl:text>
      <xsl:for-each select="//s4:token">
        <xsl:choose>
          <xsl:when test="@export='global'" />
          <xsl:otherwise>
            <xsl:value-of select="translate(ancestor::s4:package/@name,$uc,$lc)" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Редактировать: Ах, да, забыл пространство имен на выборке. Синтаксический анализатор обнаружил, что предок правильно для большинства случаев, но он все еще не может найти его, когда есть узел xsl: и целевой файл не имеет пространства имен для xsl. Я бы предпочел не изменять целевой файл, потому что это производственный код - я просто пишу инструмент autodoc.

Ответы [ 3 ]

3 голосов
/ 03 ноября 2008

Ваша проблема, вероятно, связана с пространством имен. Вы не включили их в образец дерева - можете ли вы быть немного точнее в том, что вы вставили? Предполагая, что узел пакета находится в том же пространстве имен, что и узел токена, попробуйте:

<xsl:value-of select="translate(ancestor::s4:package/@name,$uc,$lc)" />

Вы также можете проверить только неквалифицированное имя, хотя оно будет медленнее:

<xsl:value-of select="translate(ancestor::*[local-name()='package']/@name,$uc,$lc)" />

W3C local-name () spec здесь .

1 голос
/ 04 ноября 2008

Я думаю, что нет никакого способа объявить пространство имен для префикса 'xsl' в целевом документе, если вы используете процессоры XML с поддержкой пространства имен. Вы не видите никаких ошибок при попытке преобразовать целевой документ с помощью xsltproc и данной таблицы стилей?

0 голосов
/ 04 ноября 2008

Вы можете перепроверить, какую версию XSLT используют ваши инструменты. Я считаю, что XSLT 1.0 не поддерживает "предок :: ..."

...