Sto cercando di ordinare un gruppo di record in un file XML. Il trucco è che ho bisogno di ordinare usando diversi elementi per diversi nodi. Per fare un esempio semplice, voglio fare questo: dato un file XMLxsl: ordina un file XML utilizzando più elementi
<?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>
voglio convertirlo in
Andy
Joe Bumpkin
Pumpkin
Jim Zulkin
Cioè, una persona può essere elencato da qualsiasi sottoinsieme del primo nome, cognome e nick. La chiave di ordinamento è il cognome se è presente, altrimenti è il nickname se è presente e altrimenti il nome.
Sono in difficoltà qui dall'utilizzo di variabili come xsl: le chiavi di ordinamento sono apparently not allowed.
mio colpo migliore attuale è quella di avere una trasformazione in due fasi: Aggiungi un tag speciale ad ogni record utilizzando questo foglio di stile
<?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>
E poi ordinare l'XML risultante
<?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>
Mentre questa trasformazione in due passaggi funziona, mi chiedo se c'è un modo più elegante di farlo in una volta sola?
Grazie mille! –
+1 per la risposta 'fn: concat'. Ho modificato perché l'output della tua risposta non è l'output desiderato –
@ Zhenya: Prendi nota che ciò dipende in gran parte dalle lettere maiuscole. Se non puoi, a causa del tuo input, dovresti usare la concatenazione del separatore di spazi. –