2009-05-18 9 views
3

J'ai quelques XML qui contient des enregistrements et des documents sous, comme celui-ci:Déplacer les nœuds sous en parent les attributs avec XSLT

<data> 
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00"> 
     <record jsxid="id0x0b60ff10" string="101"/> 
     <record jsxid="id0x0e64d8e8" string="63"/> 
     <record jsxid="id0x2fd83f08" string="Y"/> 
    </record> 
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00"> 
     <record jsxid="id0x0b60ff10" string="102"/> 
     <record jsxid="id0x0e64d8e8" string="77"/> 
     <record jsxid="id0x2fd83f08" string="Y"/> 
    </record>  
<data> 

je dois la transformer de telle sorte que l'attribut de chaîne des enregistrements sous sont élevés en l'enregistrement parent sous forme d'attributs numérotés consécutivement, puis mis au rebut, comme ceci:

<data> 
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="101" 2="63" 3="Y"/> 
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="102" 2="77" 3="Y"/> 
<data> 

le nombre de sous-dossiers est arbitraire dans les documents, mais reste statique dans le même document.

Est-ce que quelqu'un aurait la gentillesse de montrer la voie à une solution XSLT? Merci beaucoup.

Répondre

5

est ici une solution complète:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- By default, recursively copy all nodes unchanged --> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- But don't process any children of <record> (such as whitespace)... --> 
    <xsl:template match="record/node()"/> 

    <!-- ...except for doubly-nested records; 
     convert them to attributes, named according to position --> 
    <xsl:template match="record/record" priority="1"> 
    <xsl:variable name="pos"> 
     <xsl:number/> 
    </xsl:variable> 
    <xsl:attribute name="r{$pos}"> 
     <xsl:value-of select="@string"/> 
    </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

Notez que j'ai changé le nom de vos attributs « r1 », « », etc. r2, parce que XML ne vous permet pas de commencer un nom avec un nombre.

+0

merci beaucoup Evan – mysomic

1

Cela pourrait le faire, exécutez cet extrait suivant de XSLT lors du traitement de niveau supérieur <record> éléments:

<xsl:for-each select="record"> 
    <xsl:attribute name="{position()}"> 
     <xsl:value-of select="@string" /> 
    </xsl:attribute> 
</xsl:for-each> 

Essentiellement ce itère sur chaque élément sous-<record> et crée un élément <xsl:attribute> décrivant l'attribut souhaité. La fonction position() est appelée pour obtenir la position relative dans l'élément de niveau supérieur: 1, 2, 3, etc.

Ceci n'est pas une solution complète; une certaine familiarité avec XSLT est supposée.

+0

haha, à vos risques et périls :-) – mysomic

+0

.... bien qu'il soit définitivement sur mon radar, la commande est maintenant chez Amazon. – mysomic

Questions connexes