I. Простого XSLT 1.0 Решения
Это преобразование:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/@key]">
<xsl:value-of select=
"document('')/*/my:codes/*[@key=current()]/@value"/>
</xsl:template>
</xsl:stylesheet>
при нанесении на предоставленном документе XML:
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
производит хотел, правильный результат:
<catalog>
<cd>
<title>Algebra</title>
<title>Biology</title>
<title>Chemistry</title>
</cd>
</catalog>
Объяснение:
Это стандартный способ включения встроенного XML-узел, как глобальный элемент (дочерний элемент xsl:stylesheet
), который принадлежит к (не пусто) пространство имен, отличное от пространства имен xsl.
II. Более эффективное решение XSLT 1.0, используя ключи:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:key name="kCodeByName" match="code" use="@key"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/@key]">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('')">
<xsl:value-of select=
"key('kCodeByName', $vCur)/@value"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется на том же самом документе XML (выше), то же самое правильное, хотел результат получается:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Пояснение:
Доступ к данным через функцию key()
, как правило, является сублинейным - часто O (1) и является чрезвычайно низким чем линейный поиск (что важно, если количество поисковых узлов велико).
Доступ к узлу одного документа с помощью индекса (xsl:key
) при обработке узла другого документа возможен, если документ, содержащий просматриваемый узел, является текущим документом. Чтобы получить доступ к узлам из другого документа, его корень (или узел интереса должен быть сохранен и привязан к переменной.)
III. XSLT-раствор 2,0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vCodes">
<codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</codes>
</xsl:variable>
<xsl:key name="kCodeByName" match="code" use="string(@key)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[key('kCodeByName', ., $vCodes)]">
<xsl:sequence select=
"key('kCodeByName', ., $vCodes)/@value"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется на том же самом документе XML (выше), то же самое правильное, хотел результат получается:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Пояснение:
Практически то же, что и эффективное решение XSLT 1.0, но:
В XSLT 2.0 шаблон соответствия шаблону может содержать ссылку на переменную.
В XSLT 2.0 нет необходимости в акробатических трюках, управляющих текущими и проиндексированными документами. Третий аргумент функции key()
- это указать дерево, индекс которого должен использоваться.
Благодарим за ответ. – Patan
@ User222: Добро пожаловать. –
@Dimitre Можно ли назвать шаблон в решении III. XSLT 2.0 в другом шаблоне. Если да, пожалуйста, дайте мне знать, как это сделать? –