如果子节点为空,则删除父节点

时间:2016-07-20 00:42:31

标签: xslt xslt-2.0

我正在尝试使用xslt转换给定的XML。需要注意的是,如果给定的子节点不存在,我将不得不删除父节点。我做了一些模板匹配,但我被卡住了。任何帮助将不胜感激。

输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<main>
     <item>
        <value>
           <item>
              <value>ABC</value>
              <key>test1</key>
           </item>
           <item>
              <value>XYZ</value>
              <key>test2</key>
           </item>
               <item>
              <value></value>
              <key>test3</key>
           </item>
        </value>
     </item>
     <item>
        <value />
        <key>test4</key>
     </item>
     <item>
        <value>PQR</value>
        <key>test5</key>
     </item>
</main>

预期产出:

<?xml version="1.0" encoding="UTF-8"?>
<main>
     <item>
        <value>
           <item>
              <value>ABC</value>
              <key>test1</key>
           </item>
           <item>
              <value>XYZ</value>
              <key>test2</key>
           </item>
        </value>
     </item>
     <item>
        <value>PQR</value>
        <key>test5</key>
     </item>
</main>

问题是我是否使用模板匹配,例如

deleting the parent node if child node is not present in xml using xslt中提到的

<xsl:template match="item[not(value)]"/>,然后它会完全删除所有内容,因为main / item / value也是空的。

我需要的是删除if元素是否为空但仅在元素没有子元素的情况下删除。

3 个答案:

答案 0 :(得分:1)

您应首先使用XSLT标识模板

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

然后,您只需要一个匹配item元素的模板,其中所有后代叶value元素都是空的。

 <xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" />

因此,模板匹配它,但不输出它。

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" />

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

答案 1 :(得分:0)

我认为你要删除它的元素根本没有子元素(无论这些子元素是元素还是文本节点)。尝试插入此模板:

&#13;
&#13;
<xsl:template match="item">
    <xsl:if test="exists(value/node())">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:if>
</xsl:template>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如果我读得正确,你想做:

XSLT 1.0

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

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

<xsl:template match="item[not(value[node()])]"/>

</xsl:stylesheet>

这将删除任何没有item孩子且某些内容的value