2009-09-15 25 views
10

Sto provando a canonicalizzare la rappresentazione di alcuni dati XML ordinando gli attributi di ciascun elemento in base al nome (non al valore). L'idea è di mantenere le differenze testuali minime quando gli attributi vengono aggiunti o rimossi e per impedire a editori diversi di introdurre varianti equivalenti. Questi file XML sono sotto il controllo del codice sorgente e gli sviluppatori stanno cercando di diffare le modifiche senza ricorrere a strumenti XML specializzati.Utilizzo di XSL per ordinare gli attributi

Sono stato sorpreso di non trovare un esempio XSL di come questo. Fondamentalmente voglio solo la trasformazione dell'identità con attributi ordinati. Sono venuto con la seguente con sembra funzionare in tutti i miei casi di test:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="*|/|text()|comment()|processing-instruction()"> 
    <xsl:copy> 
    <xsl:for-each select="@*"> 
     <xsl:sort select="name(.)"/> 
     <xsl:copy/> 
     </xsl:for-each> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Come n00b XSL totale Gradirei qualsiasi commento sullo stile o l'efficienza. Ho pensato che potrebbe essere utile postarlo qui poiché sembra non essere un esempio comune.

risposta

11

Con xslt essere un linguaggio funzionale fare un for-each potrebbe spesso essere il percorso più facile per noi umani ma non il più efficiente per i processori XSLT poiché non è possibile ottimizzare completamente la chiamata.

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="*"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"> 
     <xsl:sort select="name()"/> 
     </xsl:apply-templates> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="@*|comment()|processing-instruction()"> 
    <xsl:copy />  
    </xsl:template> 
</xsl:stylesheet> 

Questo è del tutto banale in questa materia anche se e come "XSL n00b" Penso che hai risolto il problema molto bene.

2

Ben fatto per risolvere il problema. Come suppongo tu sappia che l'ordine o gli attributi non sono importanti per i parser XML, quindi il vantaggio principale di questo esercizio è per gli esseri umani: una macchina li riorganizzerà su input o output in modi imprevedibili.

La canonizzazione in XML non è banale e si consiglia di utilizzare il canonicalizer fornito con qualsiasi ragionevole kit di strumenti XML anziché scrivere il proprio.

+0

Il trasformatore XSL garantisce che l'ordine specificato per gli attributi è l'ordine scritto? –

+3

Gli strumenti XML non garantiscono che qualsiasi output XML conservi l'ordine degli attributi anche se si tenta di costruirlo come sopra. Ricorda anche che non puoi nemmeno garantire quale simbolo viene usato per quotare i valori. Il confronto lessicale di XML è in genere una cattiva idea. –

Problemi correlati