How to write an xsl transform that removes certain

2019-08-16 17:41发布

Here is some example xml

<root>
    <type1></type1>
    <type2></type2>
    <type3>
        <child>3</child>
    </type3>
    <type4></type4>
    <type5></type5>
    <type6></type6>
    <type7>
        <child>7</child>
    </type7>
</root>

I want to strip all elements except type3 and type7 so that it looks like this:

<root>
    <type3>
        <child>3</child>
    </type3>
    <type7>
        <child>7</child>
    </type7>
</root>

I am new to xsl and this is what I tried

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/" >
<xsl:apply-templates/>
  </xsl:template>

  <xsl:template name="Type3">
    <xsl:copy-of select="*"/>
  </xsl:template>

 <xsl:template name="Type7">
    <xsl:copy-of select="*"/>
  </xsl:template>

</xsl:stylesheet>

This however just outputs the internal 3 and 7 from the child nodes. What is wrong with my thinking here?

Update:

While the answer below worked for this case, I am now stuck on this issue. I I have the xml

<root>
    <type1></type1>
    <type2>
        <text>
           This is a test
        </text>
    </type2>

    <type3>
        <child>3</child>
    </type3>
    <type4></type4>
    <type5></type5>
    <type6></type6>
    <type7>
        <child>7</child>
    </type7>
</root>

The XSl provided outputs:

<root>
    This is a test
    <type3>
      <child>3></child>
    </type3>
    <type7>
      <child>7</child>
    </type7>
</root>

How do I remove the text "this is a test "from showing in the final xml without affecting the internal data of the nodes I want to keep?

标签: xml xslt
1条回答
劫难
2楼-- · 2019-08-16 18:37

You can use a modified identity template with a whitelist approach:

<xsl:template match="root | node()[ancestor-or-self::type3] | node()[ancestor-or-self::type7] | comment() | processing-instruction() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template> 

<xsl:template match="text()" />     <!-- remove all text() nodes unless they are whitelisted -->

This copies

  • root, type3 and type7 elements
  • all children of type3 and type7 elements
  • all comments, processing-instructions and attributes
  • all text that is a descendant of type3 or type7
查看更多
登录 后发表回答