2013-05-01 3 views
1

J'ai une liste d'identifiants que je souhaite utiliser pour "filtrer" un fichier xml fourni. Chaque nœud de la liste doit être conservé et tous les nœuds ne figurant pas dans la liste doivent être supprimés. La difficulté pour moi est que lorsque je supprime un nœud (pas dans l'IDList), je finis par supprimer un nœud enfant qui peut être dans la liste ID. Enfin, je dois conserver l'imbrication des nœuds (voir mon exemple ci-dessous).XSLT Suppression de nœuds ne figurant pas dans une liste tout en conservant les nœuds enfants figurant dans une liste

C'est ma liste d'ID:

idlist = 2,3,5,6

Ceci est mon xml d'entrée est:

<Associations> 
    <Association ASSOCIATION_ID="1"> 
     Elmwood Association 
     <Homes/> 
    </Association> 
    <Association ASSOCIATION_ID="2"> 
     Oakwood Association 
     <Homes/> 
     <Association ASSOCIATION_ID="4"> 
      Oakwood Sub Association A 
      <Homes/> 
      <Association ASSOCIATION_ID="6"> 
       Oakwood Sub Sub Association 
       <Homes/> 
      </Association> 
     </Association> 
     <Association ASSOCIATION_ID="5"> 
      Oakwood Sub Association B 
      <Homes/> 
     </Association> 
    </Association> 
    <Association ASSOCIATION_ID="3"> 
     Cedarwood Association 
     <Homes/> 
    </Association> 
</Associations> 

Ceci est mon désiré sortie:

<Associations> 
    <Association ASSOCIATION_ID="2"> 
     Oakwood Association 
     <Homes/> 
     <Association ASSOCIATION_ID="6"> 
      Oakwood Sub Sub Association 
      <Homes/> 
     </Association> 
     <Association ASSOCIATION_ID="5"> 
      Oakwood Sub Association B 
      <Homes/> 
     </Association> 
    </Association> 
    <Association ASSOCIATION_ID="3"> 
     Cedarwood Association 
     <Homes/> 
    </Association> 
</Associations> 

Toute aide serait grandement appréciée!

Répondre

0

I. solution XSLT 2.0:

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

<xsl:param name="pIds" select="2, 3, 5, 6" as="xs:integer+"/> 

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

<xsl:template priority="2" match= 
    "Association[not(@ASSOCIATION_ID = $pIds) 
      and not(.//Association[@ASSOCIATION_ID = $pIds])]"/> 

<xsl:template match= 
    "Association[@ASSOCIATION_ID = $pIds] 
     //Association[not(@ASSOCIATION_ID = $pIds)] 
    | 
    *[not(self::Association[@ASSOCIATION_ID = $pIds])] 
     /node()[not(descendant-or-self::Association[@ASSOCIATION_ID = $pIds])] 
    "> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni:

<Associations> 
    <Association ASSOCIATION_ID="1"> 
     Elmwood Association 
     <Homes/> 
    </Association> 
    <Association ASSOCIATION_ID="2"> 
     Oakwood Association 
     <Homes/> 
     <Association ASSOCIATION_ID="4"> 
      Oakwood Sub Association A 
      <Homes/> 
      <Association ASSOCIATION_ID="6"> 
       Oakwood Sub Sub Association 
       <Homes/> 
      </Association> 
     </Association> 
     <Association ASSOCIATION_ID="5"> 
      Oakwood Sub Association B 
      <Homes/> 
     </Association> 
    </Association> 
    <Association ASSOCIATION_ID="3"> 
     Cedarwood Association 
     <Homes/> 
    </Association> 
</Associations> 

produit le résultat souhaité, correct:

<Associations> 
    <Association ASSOCIATION_ID="2"> 
     Oakwood Association 
     <Homes/> 
     <Association ASSOCIATION_ID="6"> 
       Oakwood Sub Sub Association 
       <Homes/> 
     </Association> 
     <Association ASSOCIATION_ID="5"> 
      Oakwood Sub Association B 
      <Homes/> 
     </Association> 
    </Association> 
    <Association ASSOCIATION_ID="3"> 
     Cedarwood Association 
     <Homes/> 
    </Association> 
</Associations> 

II. solution XSLT 1.0:

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

<my:ids> 
    <id>2</id> 
    <id>3</id> 
    <id>5</id> 
    <id>6</id> 
</my:ids> 

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

<xsl:template priority="2" match= 
    "Association[not(@ASSOCIATION_ID = document('')/*/my:ids/*) 
      and not(.//Association[@ASSOCIATION_ID = document('')/*/my:ids/*])]"/> 

<xsl:template match= 
    "Association[@ASSOCIATION_ID = document('')/*/my:ids/*] 
     //Association[not(@ASSOCIATION_ID = document('')/*/my:ids/*)] 
    | 
    *[not(self::Association[@ASSOCIATION_ID = document('')/*/my:ids/*])] 
     /node()[not(descendant-or-self::Association 
         [@ASSOCIATION_ID = document('')/*/my:ids/*])] 
    "> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 
+0

Dimitre, j'était incorrect de spécifier xslt-2.0, xslt-1.0 est la seule option disponible (désolé!). Lorsque j'essaie votre code, je récupère uniquement l'association avec le noeud association_Id = 2. Est-ce parce que je suis en xslt-1.0? – Schletz

+0

@ user2340911, Si votre processeur XSLT 1.0 est vraiment conforme et non bogué, vous devriez avoir reçu un message d'erreur de compilation, ou au moins un avertissement. En ce qui concerne la conversion à XSLT 1.0, cela est possible mais semblerait plutôt plus maladroit. Je vais travailler maintenant - sera en mesure d'avoir une solution XSLT 1.0 dans environ 10 heures. –

+0

@Schletz, j'ai ajouté à cette réponse une solution XSLT 1.0, comme demandé. –

Questions connexes