2009-09-15 22 views
10

Estoy tratando de canonicalizar la representación de algunos datos XML clasificando los atributos de cada elemento por nombre (no valor). La idea es mantener las diferencias textuales mínimas cuando se agregan o eliminan atributos y para evitar que diferentes editores introduzcan variantes equivalentes. Estos archivos XML están bajo el control de la fuente y los desarrolladores desean diferenciar los cambios sin recurrir a herramientas XML especializadas.Uso de XSL para ordenar atributos

Me sorprendió que no encuentre un ejemplo XSL de cómo hacerlo. Básicamente solo quiero la transformación de identidad con atributos ordenados. Se me ocurrió lo siguiente con parece que funciona en todos mis casos de prueba:

<?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> 

Como un n00b total de XSL le agradecería cualquier comentario sobre el estilo o la eficiencia. Pensé que podría ser útil publicarlo aquí, ya que parece que al menos no es un ejemplo común.

Respuesta

11

Con xslt siendo un lenguaje funcional haciendo un for-each, a menudo puede ser la ruta más fácil para nosotros los humanos, pero no la más eficiente para los procesadores XSLT ya que no pueden optimizar la llamada.

<?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> 

Esto es totalmente trivial en cuanto a este embargo y como un "n00b XSL" Creo que usted ha resuelto el problema muy bien.

2

Bien hecho para resolver el problema. Como supongo que sabe que el orden o los atributos no son importantes para los analizadores XML, por lo que el beneficio principal de este ejercicio es para los humanos: una máquina los reordenará en entradas o salidas de forma impredecible.

Canonicalization en XML no es trivial y se recomienda utilizar el canonicalizador proporcionado con cualquier kit de herramientas XML razonable en lugar de escribir el suyo.

+0

¿El transformador XSL garantiza que el orden que especifique para los atributos es la orden escrita? –

+3

Las herramientas XML no garantizan que los resultados XML conserven el orden de los atributos, incluso si intenta construirlos como se indica anteriormente. Recuerde también que ni siquiera puede garantizar qué símbolo se utiliza para citar los valores. La comparación léxica de XML suele ser una mala idea. –

Cuestiones relacionadas