首页 文章

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

提问于
浏览
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>

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

<xsl:template match="item[not(value)]"/>deleting the parent node if child node is not present in xml using xslt中所述,然后它会完全删除所有内容,因为main / item / value也是空的 .

我需要的是删除if元素是否为空但仅在元素没有子元素时执行 .

3 回答

  • 0

    您应该首先使用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>
    
  • 0

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

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

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

    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>
    

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

相关问题