I. XSLT 1.0 Solución simple
Esta transformación:
<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>
cuando se aplica sobre el documento XML proporcionado:
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
produce la querido, resultado correcto:
<catalog>
<cd>
<title>Algebra</title>
<title>Biology</title>
<title>Chemistry</title>
</cd>
</catalog>
Explicación:
Esta es la manera estándar de incluir nodo XML en línea como un elemento global (elemento secundario de xsl:stylesheet
) que pertenece a una (no vacío) espacio de nombre, diferente del espacio de nombres xsl.
II. solución más eficiente XSLT 1.0, utilizando las teclas de:
<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>
cuando se aplica esta transformación en el mismo documento XML (arriba), la misma correcta, querían resultado se produce:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Explicación:
El acceso a los datos a través de la función key()
es típicamente sub-lineal - a menudo O (1) y es extremadamente fas ter que la búsqueda lineal (que es importante si la cantidad de nodos a buscar es grande).
El acceso a un nodo de un documento mediante un índice (xsl:key
) mientras se procesa un nodo de otro documento es posible si el documento que contiene el nodo que se va a buscar es el documento actual. Para acceder a los nodos desde el otro documento, su raíz (o nodo de interés) debe guardarse y referenciarse en una variable.)
III. solución 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>
cuando se aplica esta transformación en el mismo documento XML (arriba), la misma correcta, resultado deseado se produce:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Explicación:
Casi lo mismo que la solución eficiente XSLT 1.0, pero:
En XSLT 2.0 un patrón de coincidencia de plantilla puede contiene una referencia de variable.
En XSLT 2.0 no hay necesidad de trucos acrobáticos para manipular la corriente y los documentos indexados. El tercer argumento de la función key()
es especificar el árbol cuyo índice usar.
Gracias por la Respuesta. – Patan
@ User222: De nada. –
@Dimitre ¿Podemos llamar a la plantilla en la solución III. XSLT 2.0 en otra plantilla. Si es así, ¿podría decirme cómo? –