2011-09-16 3 views
4

J'essaie de comprendre s'il existe un moyen de modifier un document XML en utilisant XSLT ou y a-t-il d'autres approches que XSLT?Modifier un document XML en utilisant XSLT

Say, j'ai un xml comme ceci:

<feed xmlns="http://www.w3.org/2005/Atom"> 
<id>http://libx.org/libx2/libapps</id> 
<entry> 
<id>http://libx.org/libx2/libapps/2</id> 
</entry> 
<entry> 
<id>http://libx.org/libx2/libapps/3</id> 
</entry> 
</feed> 

Je voudrais faire les actions suivantes:

  1. Modifier alimentation: id à (retirer le texte de l'alimentation: id)
  2. Modifier une entrée: valeurs d'id telles que la dernière valeur numérique après "/" reste.

Le xml résultat devrait ressembler à quelque chose comme ceci:

<feed xmlns="http://www.w3.org/2005/Atom"> 
<id></id> 
<entry> 
<id>2</id> 
</entry> 
<entry> 
<id>3</id> 
</entry> 
</feed> 

Merci, Sony

+0

Bonne question, +1. Oui, c'est facile dans XSLT 1.0 et trivial dans XSLT 2.0. –

Répondre

4

I. Solution XSLT 1.0:

Cette transformation XSLT 1.0 fonctionne avec une URL sans avoir aucune hypothèse sur toutes les URL Haing une sous-chaîne de départ commun:

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

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

<xsl:template match="x:feed/x:id/node()"/> 

<xsl:template match="x:entry/x:id/text()" name="eatSlashes"> 
    <xsl:param name="pText" select="."/> 

    <xsl:choose> 
    <xsl:when test="not(contains($pText, '/'))"> 
    <xsl:value-of select="$pText"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:call-template name="eatSlashes"> 
    <xsl:with-param name="pText" select= 
        "substring-after($pText, '/')"/> 
    </xsl:call-template> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

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

<feed xmlns="http://www.w3.org/2005/Atom"> 
    <id>http://libx.org/libx2/libapps</id> 
    <entry> 
     <id>http://libx.org/libx2/libapps/2</id> 
    </entry> 
    <entry> 
     <id>http://libx.org/libx2/libapps/3</id> 
    </entry> 
</feed> 

la voulu, le résultat correct est produit:

<feed xmlns="http://www.w3.org/2005/Atom"> 
    <id/> 
    <entry> 
     <id>2</id> 
    </entry> 
    <entry> 
     <id>3</id> 
    </entry> 
</feed> 

II. solution XSLT 2.0:

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

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

<xsl:template match="x:feed/x:id/node()"/> 

<xsl:template match="x:entry/x:id/text()"> 
    <xsl:sequence select="tokenize(.,'/')[last()]"/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le même document XML (ci-dessus), le même résultat correct est produit:

<feed xmlns="http://www.w3.org/2005/Atom"> 
    <id/> 
    <entry> 
     <id>2</id> 
    </entry> 
    <entry> 
     <id>3</id> 
    </entry> 
</feed> 
0

Ma connaissance de XSLT n'est pas le meilleur, mais cela semble fonctionner:

<?xml version="1.0" encoding="utf-8"?> 
<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="a:feed/a:id" xmlns:a="http://www.w3.org/2005/Atom"> 
    <xsl:copy/> 
    </xsl:template> 
    <xsl:template match="a:entry/a:id" xmlns:a="http://www.w3.org/2005/Atom"> 
    <xsl:copy><xsl:value-of select="substring-after(.,'http://libx.org/libx2/libapps/')"/></xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
Questions connexes