开发者

xslt strip node tree based on attribute

I would like to use xslt to transform an xml file into an almost identical xml file, but strip out nodes based on an attribute. If a node has an attribute, its children and it are not copied to the output file. For instance I want to strip nodes from the following xml file that have a "healthy" attribute of "not_really"

this is the xml to be transformed

<diet>

  <breakfast healthy="very">
    <item name="toast" />
    <item name="juice" />
  </breakfast>

  <lunch healthy="ofcourse">
    <item name="sandwich" />
    <item name="apple" />
    <item name="chocolate_bar" healthy="not_really" />
    <other_info>lunch is great</other_info>
  </lunch>

  <afternoon_snack healthy="not_really" >
    <item name="crisps"/>
  </afternoon_snack>

  <some_other_info>
    <otherInfo>important info</otherInfo>
  </some_other_info>
</diet>

this is the desired output

<?xml version="1.0" encoding="utf-8" ?>

<di开发者_StackOverflow社区et>

  <breakfast healthy="very">
    <item name="toast" />
    <item name="juice" />
  </breakfast>

  <lunch healthy="ofcourse">
    <item name="sandwich" />
    <item name="apple" />
    <other_info>lunch is great</other_info>
  </lunch>

  <some_other_info>
    <otherInfo>important info</otherInfo>
  </some_other_info>
</diet>

this is what I have tried (without sucess:)

<?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" indent="yes"/>

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


Two small issues:

  1. The value not_really should be in quotes, to denote that it is a text value. Otherwise, it will evaluate it as looking for an element named "not_really".
  2. Your apply-templates is selecting the nodes who's @healthy value is "not_really", you want the opposite.

Applied fixes to your stylesheet:

<?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" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()[not(@healthy='not_really')]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Alternatively, you could just create an empty template for the elements that have @healthy='not_really':

<?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" indent="yes"/>

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

  <xsl:template match="*[@healthy='not_really']"/>

</xsl:stylesheet>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜