Cómo obtener la información y ordenar, un subconjunto de elementos con identificadores únicos mediante XSLT?
Pregunta
Soy nuevo en XSLT y no puedo resolver el siguiente problema:
Tengo un archivo XML siguiente:
<root>
<subset>
<e id="A"></e>
<e id="C"></e>
</subset>
<data>
<info id="A" order="3" name="ANode"></info>
<info id="B" order="4" name="BNode"></info>
<info id="C" order="1" name="CNode"></info>
<info id="D" order="2" name="DNode"></info>
</data>
</root>
Y quiero producir esto:
<root>
<newnode id="C" order="1" name="CNode"></newnode>
<newnode id="A" order="3" name="ANode"></newnode>
</root>
Como se puede ver que la idea es "completar" el subconjunto de identificadores mediante la recuperación de la información respectiva, y clasificarlos de acuerdo a su orden especificado en <data>
.
Tenga en cuenta que <data>
se supone que tiene una gran cantidad de nodos secundarios.
Además, estoy separando los nodos con la información sobre el elemento <data>
de los subconjuntos de las identificaciones, porque voy a tener muchos subconjuntos y no quiere tener información repetida "en todas partes".
Gracias de antemano.
Solución
También puede teclear fuera del subconjunto dependiendo de qué otra cosa puede que tenga que ver con los datos reales.
<xsl:output indent="yes" />
<xsl:key name="subset" match="e" use="@id" />
<xsl:template match="/">
<root>
<xsl:for-each select="//info[count(key('subset',@id)[1]) > 0]">
<xsl:sort select="@order" data-type="number" />
<newnode id="{@id}" order="{@order}" name="{@name}" />
</xsl:for-each>
</root>
</xsl:template>
Otros consejos
Las referencias cruzadas piden el uso de teclas:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="k1" match="info" use="@id"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="subset/e">
<xsl:sort select="key('k1', @id)/@order" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="e">
<newnode id="{@id}" order="{key('k1', @id)/@order}" name="{key('k1', @id)/@name}"/>
</xsl:template>
</xsl:stylesheet>
Esto debería hacer por la muestra de entrada que presenta.