71 votes

Comment supprimer des éléments de xml en utilisant xslt avec feuille de style et xsltproc ?

J'ai beaucoup de fichiers XML qui ont quelque chose de ce genre :

<Element fruit="apple" animal="cat" />

Que je veux supprimer du fichier.

En utilisant une feuille de style XSLT et l'utilitaire de ligne de commande Linux xsltproc, comment pourrais-je faire cela ?

À ce stade du script, je dispose déjà de la liste des fichiers contenant l'élément que je souhaite supprimer, de sorte que le fichier unique peut être utilisé comme paramètre.


EDIT : la question était à l'origine dépourvue d'intention.

Ce que j'essaie de faire, c'est de supprimer tout l'élément "Element" où (fruit=="apple" && animal=="cat"). Dans le même document, il y a de nombreux éléments nommés "Element", je souhaite qu'ils soient conservés. Donc

<Element fruit="orange" animal="dog" />
<Element fruit="apple"  animal="cat" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />

Deviendrait :

<Element fruit="orange" animal="dog" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />

136voto

Dimitre Novatchev Points 147842

Utilisation de l'un des modèles de conception XSLT les plus fondamentaux : "Overriding the transformation identitaire "on écrira simplement ce qui suit :

<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="Element\[@fruit='apple' and @animal='cat'\]"/>
</xsl:stylesheet>

Prenez note comment le deuxième modèle remplace le modèle identity (1st) uniquement pour les éléments nommés "Element" qui ont un attribut "fruit" avec la valeur "apple" et un attribut "animal" avec la valeur "cat". Ce modèle a un corps vide, ce qui signifie que l'élément correspondant est simplement ignoré (rien n'est produit lorsqu'il est correspondant).

Lorsque cette transformation est appliquée sur le document XML source suivant :

<doc>... 
    <Element name="same">foo</Element>...
    <Element fruit="apple" animal="cat" />
    <Element fruit="pear" animal="cat" />
    <Element name="same">baz</Element>...
    <Element name="same">foobar</Element>...
</doc>

le résultat souhaité est produit :

<doc>... 
    <Element name="same">foo</Element>...
    <Element fruit="pear" animal="cat"/>
    <Element name="same">baz</Element>...
    <Element name="same">foobar</Element>...
</doc>

Vous trouverez d'autres exemples d'utilisation et de remplacement du modèle d'identité dans le document suivant aquí .

13 votes

Bien que je n'aie même pas posé la bonne question, vous avez répondu exactement à ce que j'aurais dû demander :)

3 votes

Pourquoi ne pas marquer ce message comme étant la bonne réponse alors ? Il disparaîtrait alors de la liste des problèmes non résolus.

2 votes

J'ai dû attendre de vérifier que ça marchait, et je n'en ai pas eu l'occasion au travail aujourd'hui. C'est fait maintenant, merci Dimitre.

3voto

Sboisen Points 31

La réponse de @Dimitre Novatchev est certainement à la fois correct et élégant, mais il y a une généralisation (que le PO n'a pas demandée) : que se passe-t-il si l'élément que vous voulez filtrer a également des éléments enfants ou du texte que vous voulez garder ?

Je pense que cette variation mineure couvre ce cas :

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

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

    <!-- drop DropMe elements, keeping child text and elements -->
    <xsl:template match="DropMe">
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

La condition de correspondance peut être compliquée pour spécifier d'autres attributs, etc., et vous pouvez utiliser plusieurs modèles de ce type si vous laissez tomber d'autres choses.

Donc cette entrée :

<?xml version="1.0" encoding="UTF-8"?>
<mydocument>
    <p>Here's text to keep</p>
    <p><DropMe>Keep this text but not the element</DropMe>; and keep what follows.</p>
    <p><DropMe>Also keep this text and <b>this child element</b> too</DropMe>, along with what follows.</p>
</mydocument>

produit cette sortie :

<?xml version="1.0" encoding="UTF-8"?><mydocument>
    <p>Here's text to keep</p>
    <p>Keep this text but not the element; and keep what follows.</p>
    <p>Also keep this text and <b>this child element</b> too, along with what follows.</p>
</mydocument>

Crédit à Livre de cuisine XSLT .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X