2011-04-07 3 views
2

Comment puis-je utiliser XSLT, ne sélectionner que certaines balises xml de mon XML d'entrée à mon XML de sortie? entrée exemple:utiliser XSLT pour réduire la sortie XML

<Country value="USA"> 
    <State value="KY> 
     <City value="Hebron" /> 
     <City value="Lexington" /> 
     <City value="Owensboro" /> 
     <City value="Jonesville" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
     <City value="Columbus" /> 
     <City value="Cleveland" /> 
     <City value="Jonesville" /> 
    </State> 
    <State value="IN" > 
     <City value="Indianapolis" /> 
    </State> 
</Country> 

Alors, gardez les balises Pays/régionaux en place et seulement copier Hébron et Cincinnati?

résultat attendu:

<Country value="USA"> 
    <State value="KY> 
     <City value="Hebron" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
    </State> 
</Country> 
+1

Qu'est-ce qui définit les balises que vous souhaitez conserver? Première dans chaque état? –

+0

Puisque vous avez un tag '', il est implicite que vous aurez d'autres pays, dans lesquels '' pourrait ne pas être approprié (Province, Préfecture, etc). Vous devez spécifier complètement le problème. –

+0

Il peut y avoir plus d'un pays mais pour cet exemple (pas les vrais tags), l'état suffira pour les provinces d'autres pays ... –

Répondre

2

La feuille de style suivante:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="City[not(@value='Hebron' or @value='Cincinnati')]" /> 
</xsl:stylesheet> 

Sur cette entrée:

<Country value="USA"> 
    <State value="KY"> 
     <City value="Hebron" /> 
     <City value="Lexington" /> 
     <City value="Owensboro" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
     <City value="Columbus" /> 
     <City value="Cleveland" /> 
    </State> 
</Country> 

le résultat suivant:

<Country value="USA"> 
    <State value="KY"> 
     <City value="Hebron" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
    </State> 
</Country> 

Cette feuille de style utilise le identity transform pour copier tous, mais les noeuds indésirables à la sortie inchangée.

Un autre exemple

Vous pouvez également supprimer tout élément State qui ne dispose pas d'une ville souhaitée. Cette feuille de style:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="City[not(@value='Hebron' or @value='Cincinnati')]"/> 
    <xsl:template 
      match="State[not(City[@value='Hebron' or @value='Cincinnati'])]"/> 
</xsl:stylesheet> 

à cette entrée:

<Country value="USA"> 
    <State value="KY"> 
     <City value="Hebron" /> 
     <City value="Lexington" /> 
     <City value="Owensboro" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
     <City value="Columbus" /> 
     <City value="Cleveland" /> 
    </State> 
    <State value="MO"> 
     <City value="St. Louis" /> 
    </State> 
</Country> 

Produit:

<Country value="USA"> 
    <State value="KY"> 
     <City value="Hebron" /> 
    </State> 
    <State value="OH"> 
     <City value="Cincinnati" /> 
    </State> 
</Country> 
1

Cela laissera seulement certaines villes:

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


<xsl:template match="City[@value != 'Hebron' and @value != 'Cincinnati']"/> 

Cela laissera seulement la première ville:

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


<xsl:template match="City[position() &gt; 1]"/> 
1

Voici mon (probablement insuffisant) solution 2.0. Les villes sont une expression régulière passée en paramètre.

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

    <xsl:param name="Cities" select="'Cincinnati|Hebron'"/> 

    <xsl:template match="State"> 
    <xsl:if test="exists(City[matches(@value, $Cities)])"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="State/City"> 
    <xsl:if test="matches(@value, $Cities)"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 

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

</xsl:stylesheet> 
+0

@stand: Le paramètre –

+0

@Alejandro: Oui, je pensais que peut-être une regexp donnerait plus de flexibilité, donc vous pourriez choisir "Villes qui commencent par C" ou des choses comme ça. à l'aise avec regexes qui est un tout autre problème. – stand

+0

@stand: Mais plus important encore, vous ne devez pas ouvrir une fenêtre pour l'échec de la feuille de style en autorisant un paramètre qui pourrait contenir un RegExp interdit correspondant à la séquence vide. –