2009-10-09 9 views
1

J'ai xml comme ceci:Ajout d'un nœud à l'autre dans XSLT

<configurationData> 
    <path name='b'> 
     <path name='a'> 
     <setting name='s1'> 
     ![CDATA[XXXX]] 
     </setting> 
     <setting name='s2'> 
      XXXX 
     </setting> 
     </path> 
    </path> 
    </configurationData> 

où DonnéesConfiguration est le nœud racine, et il peut y avoir des chemins peut imbriquée suivie par un ou plusieurs noeuds de réglage. Je veux convertir le nœud de paramètre pour mettre le contenu du nœud de réglage dans un nœud enfant appelé valeur

<configurationData> 
    <path name='b'> 
     <path name='a'> 
     <setting name='s1'> 
      <value>![CDATA[XXXX]]</value> 
     </setting> 
     <setting name='s2'> 
      <value>XXXX</value> 
     </setting> 
     </path> 
    </path> 
    </configurationData> 

Je dois admettre que je trouve XML un bloc de route mentale et je ne vois pas ce que XSLT à utiliser:

Ceci est ma tentative:

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

    <xsl:output encoding ="utf-8" indent="yes" method="xml" version="1.0"/> 

    <xsl:template match='/setting'> 
    <xsl:apply-templates select='setting' /> 
    </xsl:template> 

    <xsl:template match='setting'> 
    <value> 
     <xsl:value-of select='.'/> 
    </value> 
    </xsl:template> 
</xsl:stylesheet> 
+2

+1 pour montrer votre travail –

Répondre

3

Vous êtes 90% du chemin. Ce dont vous avez besoin est le "modèle d'identité"

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

    <xsl:output encoding ="utf-8" indent="yes" method="xml" version="1.0"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match='setting'> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <value> 
       <xsl:value-of select='.'/> 
      </value> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Le premier modèle traite tous les nœuds, en les copiant dans la sortie. Cependant, le modèle 'setting', étant plus spécifique, est invoqué pour les nœuds 'setting', Ce modèle copie le nœud lui-même et ses attributs, puis encapsule la valeur dans une balise 'value'. La chose la moins intime à propos de XSLT est que la feuille de style n'est pas un programme qui pilote le processus. Au lieu de cela, c'est le document XML d'entrée qui contrôle, avec la feuille de style fournissant des instructions qui sont sélectionnées et exécutées en fonction de ce qui est dans l'entrée. C'est ce qu'on appelle le traitement "push". Le processeur XSL pousse les données vers votre feuille de style. XSLT dispose de certaines fonctionnalités et vous pouvez écrire une feuille de style dans le style "pull", où la feuille de style tente de piloter le processus, mais cela est plus difficile et conduit à des feuilles de style difficiles à maintenir.

Edit: Pour activer les sections CDATA remplacerons:

<xsl:value-of select='.' /> 

avec

![CDATA[<xsl:value-of select='.' disable-output-escaping="yes"/>]] 

(mais pas la meilleure solution car il met toujours CDATA)

+1

Fantastique jim. Un seul petit problème - l'information CDATA est translittérée. J'ai besoin du CDATA conservé en tant que CDATA. –

+0

Juste une pensée. Je suppose que je pourrais juste utiliser un CDATA toujours pas je? –

+1

@Preet Sangha: Oui, en déclarant 'cdata-section-elements' - voir ma réponse. Cependant, je ne m'inquiéterais pas si ça sort comme CDATA ou pas, puisque sur le "niveau de données" c'est équivalent. – Tomalak

0

Ma suggestion, sur la base Jim Garrison réponse:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:output method="xml" encoding="utf-8" cdata-section-elements="value" /> 

    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="setting/text()"> 
    <value> 
     <xsl:value-of select="." /> 
    </value> 
    </xsl:template> 

</xsl:stylesheet> 
+0

merci beaucoup. pourriez-vous indiquer pourquoi cela pourrait être mieux s'il vous plaît? –

+0

C'est un peu moins complexe et plus idiomatique. A part ça, il n'y a pas beaucoup de différence. – Tomalak