2008-11-26 7 views
2

Version courte:LINQ ou XSLT pour transformer un élément en un autre dans Visual Basic 9

Quelqu'un pourrait-il proposer ou de fournir un échantillon dans LINQ to XML pour VB, ou dans un XSLT de la façon de changer un élément XML dans un autre (sans coder en dur une copie élément par élément de tous les éléments inchangés)?

Contexte:

J'ai un fichier XML, que je pense est bien formé, qui contient une entrée racine qui est <collection> et multiples <dvd> éléments. Dans un DVD, il y a des Genres et des Tags, comme indiqué ci-dessous. (J'ai coupé beaucoup d'autres éléments pour la simplicité).

Ce que je veux faire est de <Tag éléments <Tag> qui pourraient être présents dans un supplémentaire <Genre>. Par exemple, dans l'entrée ci-dessous, je dois ajouter <Genre> Kids </Genre>. (Je réalise que c'est en fait l'attribut NAME de l'élément TAG que je cherche à transformer en l'élément GENRE, mais si je pouvais même imaginer comment créer un nouveau GENRE appelé "Tag", je serais beaucoup plus en avance et pourrait probablement résoudre le reste.)

Je n'ai jamais rien fait avec XML. Ma compréhension est que je pourrais utiliser un fichier de transformation XSLT et un XSLCompiledTransform ou je pourrais utiliser LINQ en XML (j'ai Visual Basic 9, et je préférerais faire tout cela à l'intérieur de VB). [Je suis sûr qu'il existe un certain nombre d'autres approches, aussi.]

Le problème est, je ne trouve pas d'exemples de syntaxe XSLT ou LINQ qui me disent comment transformer un élément en un autre. Je pourrais écrire assez de LINQ pour copier tous les éléments un par un, mais il doit y avoir un moyen plus facile que de coder en dur une copie de tous les éléments qui ne changent pas! (Il doit y avoir!)

Donc, si quelqu'un qui sait pourrait me donner un exemple ou me donner un coup de main avec un peu de code de démarrage dans LINQ ou XSLT, je serais éternellement reconnaissant (OK, peut-être pas pour toujours, mais au moins pour longtemps!).

Merci.

XML Exemple:

<Collection> 
    <DVD> 
    <ID>0000502461</ID> 
    <Title>Cirque du Soleil: Alegría</Title> 
    <Released>2002-05-31</Released> 
    <RunningTime>90</RunningTime> 
    <Genres> 
     <Genre>Family</Genre> 
     <Genre>Music</Genre> 
    </Genres> 
    <Overview>What if anything were possible? What if ... 
    </Overview> 
    <Notes/> 
    <Tags> 
     <Tag Name="Kids" FullName="Kids"/> 
    </Tags> 
    </DVD> 
</Collection> 

Répondre

0

Vous cherchez quelque chose comme ceci:

<xsl:template match="Tag"> 
    <xsl:element name="Genre"> 
     <xsl:value-of select="@Name"/>   
    </xsl:element>  
    </xsl:template> 
1

Vous pouvez faire correspondre un nœud avec node(), comme ceci:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<!-- Uncomment to remove Tags elements --> 
<!-- <xsl:template match="Tags" /> --> 

<xsl:template match="Genres"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     <xsl:for-each select="../Tags/Tag"> 
      <xsl:element name="Genre"> 
       <xsl:value-of select="@Name" /> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<!-- Default rule: Copy node and descend --> 
<xsl:template match="@*|node()"> 
     <xsl:copy> 
       <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
2

En utilisant l'un des les modèles de conception XSLT les plus fondamentaux et les plus puissants: remplacer le identity template, le e rédigera cette transformation très simple pour remplacer tous les éléments "Genres" avec un élément "Sujets":

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

<xsl:output omit-xml-declaration="yes"/> 

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

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

Lorsqu'il est appliqué sur le document XML source fourni:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Genres> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
     </Genres> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

Le résultat recherché est produit:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Topics> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
     </Topics> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

Le premier modèle de la feuille de style est la règle d'identité. Il copie tout nœud correspondant inchangé et applique récursivement des modèles à ses attributs ou enfants.Si aucun autre modèle n'est présent, ce modèle crée une copie identique du document XML source, d'où son nom. Lorsqu'il existe un modèle plus spécifique (spécifiant des détails plus spécifiques pour le nœud correspondant, tel que le nom et/ou d'autres conditions), il est dit de "surcharger" les modèles plus génériques. Cela signifie que le modèle le plus spécifique est choisi pour le traitement du noeud.

En utilisant ce modèle de conception extrêmement puissant, il est trivial de implementin quelques lignes telles que le traitement:

  1. Supprimer tous les nœuds qui satisfont certaines conditions.
  2. Renommez tous les nœuds répondant à certaines conditions.
  3. Modifier le contenu de tous les noeuds qui satisfont une condition

tout en copiant tous les autres nœuds intacts.

Dans notre cas, le second modèle est plus spécifique et il est sélectionné pour le traitement de chaque élément nommé "Genres". Tout ce qu'il fait est de créer un élément nommé "Sujets" et à l'intérieur, il applique des modèles à tous les attributs de nœuds et enfants actuels.

Enfin, la transformation suivante ajoutera un nouvel élément "Genre" aux enfants de "Genres", pour chaque élément "Tag":

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

<xsl:output omit-xml-declaration="yes"/> 

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

    <xsl:template match="Genres"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     <xsl:apply-templates select="../Tags/Tag" mode="Gen"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Tag" mode="Gen"> 
     <Genre> 
     <xsl:value-of select="@Name"/> 
     </Genre> 
    </xsl:template> 
</xsl:stylesheet> 

Le résultat est à nouveau au besoin:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Genres> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
 <Genre>Kids</Genre> 
 
     </Genres> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

Plus d'extraits de code utilisant le modèle "règle d'identité" peuvent être trouvés here.

+0

Belle explication, mais la deuxième règle de style et le résultat (pas de différence à l'entrée?!) Semblent faux – phihag

+0

S'il vous plaît, regardez attentivement. Le résultat est différent de l'entrée. L'élément "Genres" n'est plus là et il a été remplacé par un élément "Topics". C'est exactement ce que cette question demande d'accomplir: remplacer un élément spécifique par un autre élément –

+0

Oh, j'ai vu que l'OP voulait aussi qu'un nouveau "Genre" soit ajouté, correspondant à chaque "Tag" ... :(Fait! –

Questions connexes