Estoy tratando de ordenar un grupo de registros en un archivo XML. El truco es que necesito ordenar usando diferentes elementos para diferentes nodos. Para dar un ejemplo más simple, yo quiero hacer esto: dado un archivo XMLxsl: ordena un archivo XML usando múltiples elementos
<?xml version="1.0" encoding="utf-8" ?>
<buddies>
<person>
<nick>Jim</nick>
<last>Zulkin</last>
</person>
<person>
<first>Joe</first>
<last>Bumpkin</last>
</person>
<person>
<nick>Pumpkin</nick>
</person>
<person>
<nick>Andy</nick>
</person>
</buddies>
quiero convertirlo en
Andy
Joe Bumpkin
Pumpkin
Jim Zulkin
Es decir, una persona puede aparecer por cualquier subconjunto de la primera nombre, apellido y un nick. La clave de clasificación es el apellido si está presente; de lo contrario, es el alias si está presente y un nombre diferente.
Tengo dificultades aquí ya que el uso de variables como xsl: claves de clasificación es apparently not allowed.
Mi actual mejor tiro es tener una transformación de dos pasos: Agregar una etiqueta especial para cada registro usando esta hoja de estilo
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<!-- *** convert each person record into a person2 record w/ the sorting key *** -->
<xsl:template match="/buddies">
<buddies>
<xsl:for-each select="person">
<person2>
<xsl:copy-of select="*"/>
<!-- add the sort-by tag -->
<sort-by>
<xsl:choose>
<xsl:when test="last"> <xsl:value-of select="last"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="nick"> <xsl:value-of select="nick"/> </xsl:when>
<xsl:otherwise> <xsl:value-of select="first"/> </xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</sort-by>
</person2>
</xsl:for-each>
</buddies>
Y a continuación, ordenar el XML resultante
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/buddies">
<xsl:apply-templates>
<xsl:sort select="sort-by"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="person2">
<xsl:value-of select="first"/>
<xsl:value-of select="nick"/>
<xsl:value-of select="last"/><xsl:text>
</xsl:text>
</xsl:template>
Si bien esta transformación de dos pasos funciona, me pregunto si hay una forma más elegante de hacerlo de una sola vez.
¡Gracias un trillón! –
+1 para la respuesta 'fn: concat'. He editado porque su salida de respuesta no es la salida deseada –
@Zhenya: tenga en cuenta que esto se basa en gran medida en las mayúsculas. Si no puede debido a su entrada, debe usar la concatenación del separador de espacio. –