【问题标题】:Modify xml document using XSLT使用 XSLT 修改 xml 文档
【发布时间】:2011-09-16 22:49:51
【问题描述】:

我想了解是否有一种方法可以使用 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 为(去掉 feed:id 的文字)
  2. 修改 entry:id 值,以便保留“/”之后的最后一个数字值。

结果 xml 应该如下所示:

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

谢谢, 索尼

【问题讨论】:

  • 好问题,+1。是的,这在 XSLT 1.0 中很容易,在 XSLT 2.0 中微不足道。

标签: xml xslt


【解决方案1】:

我。 XSLT 1.0 解决方案:

此 XSLT 1.0 转换适用于任何 url,无需假设所有 URL 具有共同的起始子字符串:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      相关资源
      最近更新 更多