I. Proste XSLT 1.0 Rozwiązanie
Ta przemiana:
<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>
po naniesieniu na dostarczonych dokumentów XML:
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
produkuje chciał, poprawny wynik:
<catalog>
<cd>
<title>Algebra</title>
<title>Biology</title>
<title>Chemistry</title>
</cd>
</catalog>
Wyjaśnienie:
Jest to standardowy sposób z tym węzeł inline XML jako element globalnej (element dzieckiem xsl:stylesheet
), który należy do (niepusty) przestrzeń nazw, inna niż przestrzeń nazw xsl.
II. Bardziej wydajny XSLT 1.0 rozwiązanie, za pomocą klawiszy:
<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>
kiedy ta transformacja jest stosowane na tym samym dokumencie XML (powyżej), tak samo poprawne, chciał wynik jest produkowany:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Objaśnienie::
Dostęp do danych za pomocą funkcji key()
jest zwykle podrzędny - często O (1) i jest wyjątkowo fas ter wyszukiwania liniowego (co jest ważne, jeśli liczba przeszukiwanych węzłów jest duża).
Uzyskiwanie dostępu do węzła jednego dokumentu za pośrednictwem indeksu (xsl:key
) podczas przetwarzania węzła innego dokumentu jest możliwe, jeśli dokument zawierający węzeł, który ma zostać sprawdzony, jest bieżącym dokumentem. Aby uzyskać dostęp do węzłów z innego dokumentu, jego katalog główny (lub węzeł zainteresowania musi być zapisany i odwoływany do zmiennej.)
III. XSLT 2.0 rozwiązanie:
<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>
kiedy ta transformacja jest stosowane na tym samym dokumencie XML (powyżej), tak samo poprawne, chciał wynik jest produkowany:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
wyjaśnienie:
Prawie tak samo, jak wydajne rozwiązanie XSLT 1.0, ale:
W XSLT 2.0 wzór dopasowania szablonu może zawierać odniesienie do zmiennej.
W XSLT 2.0 nie ma potrzeby akrobatycznych sztuczek manipulacji prąd i indeksowane dokumenty - 3rd argumentu funkcji key()
jest określenie drzewa, którego indeks w użyciu.
Dziękuję za odpowiedź. – Patan
@ Użytkownik222: Nie ma za co. –
@Dimitre Czy możemy nazwać szablon w rozwiązaniu III. XSLT 2.0 w innym szablonie. Jeśli tak, proszę dać mi znać, w jaki sposób? –