2009-03-17 13 views
17

Nous avons un système actuel qui génère un fichier XML qui est dans le format suivant:Conversion des éléments XML aux attributs XML en utilisant XSLT

<INVENTORY> 
    <ITEM> 
     <SERIALNUMBER>something</SERIALNUMBER> 
     <LOCATION>something</LOCATION> 
     <BARCODE>something</BARCODE> 
    </ITEM> 
</INVENTORY> 

-je utiliser ces données pour charger dans la norme réseau .NET 2.0 . Mais la grille a besoin du XML pour être dans le format suivant:

<INVENTORY> 
    <ITEM serialNumber="something" location="something" barcode="something"> 
    </ITEM> 
</INVENTORY> 

dire doivent être convertis les nœuds enfants du point dans les attributs du nœud de l'élément. Est-ce que quelqu'un sait comment cela peut être fait en utilisant XSLT?

+0

Veuillez lire la documentation de balisage, vous avez besoin de 4 espaces ou d'un onglet pour que SO reconnaisse le code. – AnthonyWJones

+0

La réponse que vous avez acceptée ne produit pas le résultat que vous voulez !!! Un nom d'attribut doit être "serialNumber", la solution acceptée produit "serialnumber". La prochaine fois, n'induisez pas les gens qui passent leur temps à aider. –

Répondre

27

Cela devrait fonctionner:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="INVENTORY"> 
    <INVENTORY> 
     <xsl:apply-templates/> 
    </INVENTORY> 
    </xsl:template> 

    <xsl:template match="ITEM"> 
    <ITEM> 
     <xsl:for-each select="*"> 
     <xsl:attribute name="{name()}"> 
      <xsl:value-of select="text()"/> 
     </xsl:attribute> 

     </xsl:for-each> 
    </ITEM> 
    </xsl:template> 
</xsl:stylesheet> 

HTH

+0

Merci pour toutes vos suggestions, mais celui-ci semble être la solution la plus simple et la plus dynamique :) et a fonctionné pour moi :) – eMTeeN

2

Cela devrait le faire:

<xsl:for-each select="//ITEM"> 
    <xsl:element name="ITEM"> 
     <xsl:attribute name="serialNumber"> 
     <xsl:value-of select="SERIALNUMBER"/> 
     </xsl:attribute> 
     <xsl:attribute name="location"> 
     <xsl:value-of select="LOCATION"/> 
     </xsl:attribute> 
     <xsl:attribute name="barcode"> 
     <xsl:value-of select="BARCODE"/> 
     </xsl:attribute> 
    </xsl:element> 
    </xsl:for-each> 

Ou en utilisant le raccourci de David:

<xsl:for-each select="//ITEM"> 
    <ITEM serialNumber="{SERIALNUMBER}" location="{LOCATION}" barcode="{BARCODE}"/> 
</xsl:for-each> 
2

Si votre source ressemble à ceci:

<row><a>1</a><b>2</b></row> 

et vous voulez qu'il ressemble ceci:

<row a="1" b="2" /> 

alors ce XSLT devrait fonctionner:

<xsl:template match="row"> 
    <row a="{a}" b="{b}" /> 
</xsl:template> 
4

Ces deux modèles devraient le faire: -

<xsl:template match="ITEM"> 
    <ITEM serialNumber="{SERIALNUMBER}" location="{LOCATION}" barcode="{BARCODE}" /> 
</xsl:template> 

<xsl:template match="INVENTORY"> 
    <INVENTORY> 
     <xsl:apply-templates /> 
    </INVENTORY> 
</xsl:template> 
4

Voici probablement la solution la plus simple sur qui convertit tous les enfants-éléments de ITEM à ses attributs et va tout reproduire ailleurs tout comme, tout en convertissant les noms d'éléments à tous les noms d'attributs souhaités:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<!--            --> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="vrtfNameMapping"> 
    <item name="SERIALNUMBER" newName="serialNumber"/> 
    <item name="LOCATION" newName="location"/> 
    <item name="BARCODE" newName="barcode"/> 
    </xsl:variable> 
<!--            --> 
    <xsl:variable name="vNameMapping" select= 
    "document('')/*/xsl:variable[@name='vrtfNameMapping']"/> 
<!--            --> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
<!--            --> 
    <xsl:template match="ITEM/*"> 
    <xsl:attribute name= 
    "{$vNameMapping/*[@name=name(current())]/@newName}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

lorsque la transformation ci-dessus est appliquée sur la condition document XML:

<INVENTORY> 
    <ITEM> 
     <SERIALNUMBER>something</SERIALNUMBER> 
     <LOCATION>something</LOCATION> 
     <BARCODE>something</BARCODE> 
    </ITEM> 
</INVENTORY> 

le résultat recherché est produit:

<INVENTORY> 
    <ITEM serialNumber="something" location="something" barcode="something"/> 
</INVENTORY> 

Prenez note les suivantes:

  1. L'utilisation du identity rule

  2. L'utilisation de <xsl:strip-space elements="*"/>

  3. L'utilisation de la variable vrtfNameMapping sans aucune fonction d'extension xxx:node-set() .

  4. Le fait que nous gérons tout mappage entre un nom et un nouveauNom, et pas seulement un casse inférieur simple.

+0

Ne ressemble pas à cette transformation fonctionne. Cela ne produit aucun résultat. Simplement ceci: Mark

+0

@ Mark, Cela signifie que vous avez soit un processeur XSLT buggy, ou vous n'avez pas copié et collé exactement Document XML et la transformation. Je viens de ré-exécuter la transformation - le même résultat est produit avec plusieurs processeurs XSLT –

Questions connexes