更改标记名称并删除特定值的元素

时间:2012-06-27 08:29:35

标签: xml xslt

无法遍历子元素。在下面的输入XML中,我必须只使用元素<e>并将其替换为<se>,如果值等于“DB1”,则需要删除一个元素<e>。有人可以帮忙吗?我是XSLT的新手。

输入XML:

<a xmlns="http://examle.com/test/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
  <b>
     <c name="RES" type="KSD">
     <d>
        <e>DB1</e>
        <e>DB2</e>
        <e>DB3</e>      
     </d>
    </c>
  </b>
  <error count="0" success="OK">
  </error>
</a>

所需的输出XML是:

<?xml version="1.0" encoding="utf-8" ?>
<Payload xmlns="http://example.com/test/2.0"xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <response>
        <allot>8</allot>            
        <size>200</size>
        <ses>
            <se>DB2</se>
            <se>DB3</se>
        </ses>          
    </response>
</Payload>

2 个答案:

答案 0 :(得分:0)

在我看来最接近你需要的解决方案(非常模糊)是

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" />

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

    <!-- rename -->
    <xsl:template match="a">
      <Payload>
        <xsl:apply-templates select="@*|node()"/>
      </Payload>
    </xsl:template>

    <!-- rename and add some new elements -->
    <xsl:template match="b">
      <response>
        <allot>8</allot>            
        <size>200</size>
        <xsl:apply-templates select="@*|node()"/>
      </response>
    </xsl:template>

    <!-- don't output this node but only its children -->
    <xsl:template match="c">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

    <!-- rename -->
    <xsl:template match="d">
      <ses>
        <xsl:apply-templates select="@*|node()"/>
      </ses>
    </xsl:template>

    <!-- rename -->
    <xsl:template match="e">
      <se>
        <xsl:apply-templates select="@*|node()"/>
      </se>
    </xsl:template>

    <!-- discard -->
    <xsl:template match="e[.='DB1']|error"/>

</xsl:stylesheet>

我无法处理命名空间,因此我从输入中删除了xmlns命名空间,并且它有效。

答案 1 :(得分:0)

我已经写过这样的XSLT转换了。

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

  <xsl:template match="@*|comment()|processing-instruction()|text()">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="d" >
    <Payload xmlns="http://example.com/test/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
      <response>
        <allot>8</allot>
        <size>200</size>
        <ses>
          <xsl:for-each select="e">
            <xsl:variable name="e_name" select="."></xsl:variable>
            <xsl:if test="$e_name != 'DB1'">
              <se>
                <xsl:value-of select="." />
              </se>
            </xsl:if>
          </xsl:for-each>
        </ses>
      </response>
    </Payload>
  </xsl:template>

</xsl:stylesheet>