使用XSLT修改xml文档

时间:2011-09-16 22:49:51

标签: xml xslt

我试图了解是否有办法使用XSLT修改xml文档,还是有其他比XSLT更好的方法?

说,我有一个像这样的xml:

<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>

我想做以下行动:

  1. 修改Feed:id to(删除Feed:id的文字)
  2. 修改条目:id值,使“/”之后的最后一个数字值保持不变。
  3. 结果xml看起来应该是这样的:

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

    谢谢, 索尼

2 个答案:

答案 0 :(得分:4)

予。 XSLT 1.0解决方案:

此XSLT 1.0转换可以与任何网址一起使用,而不会对所有具有共同起始子字符串的网址进行任何假设:

<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>

应用于提供的XML文档

<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>

产生了想要的正确结果

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

<强> II。 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>

应用于同一XML文档(上图)时,会生成相同的正确结果

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

答案 1 :(得分:0)

我对XSLT的了解并不是最好的,但这似乎有效:

<?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>