使用Java或XSLT从XML中删除指定的空标记集

时间:2016-09-30 07:10:11

标签: java xml xslt

如果它们是空的,我需要从XML中删除一组指定的标记。

例如:

<xml><tag1>value<tag1><tag2></tag2><tag3>value<tag3><tag4/><tag5/><xml>

在此,要删除的标签(如果它们是空的)是:

tag2, tag4

预期结果:

<xml><tag1>value<tag1><tag3>value<tag3><tag5/><xml>

使用普通Java或XSLT实现此目的的最佳方法是什么?除此之外,我们还有第三方库可以用于同一件事吗?

此致 Anoop

2 个答案:

答案 0 :(得分:1)

  如果XML是空的,则

标记。

什么是空的?&#34;空&#34;有不同的可能定义:

  1. 没有孩子
  2. 无文字
  3. 没有空白文本节点(例如&#39;&#39;,CR,NL,#x20, #x9, #xD or #xA.
  4. 以上的组合
  5. 测试 - 学习输入:

    <root>
        <tag1>value</tag1>
        <tag2></tag2>
        <tag3><tag3_1/></tag3>
        <tag4><tag4_1/> </tag4>
        <tag5> </tag5>
        <tag6/>
        <tag7>
    
        </tag7>
    </root>
    

    测试 - 学习转型:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
    
        <xsl:template match="root">
    
            <!-- no childs (element nodes) -->
            <xsl:text>"*[not(*)]" matches: </xsl:text>
            <xsl:for-each select="*[not(*)]">
                <xsl:value-of select="name()"/><xsl:text> </xsl:text>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
    
            <!-- see function node() in thread -->
            <xsl:text>"*[not(node())]" matches: </xsl:text>
            <xsl:for-each select="*[not(node())]">
                <xsl:value-of select="name()"/><xsl:text> </xsl:text>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
    
            <!-- no textnodes -->
            <xsl:text>"*[not(text())]" matches: </xsl:text>
            <xsl:for-each select="*[not(text())]">
                <xsl:value-of select="name()"/><xsl:text> </xsl:text>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
    
            <!-- no textnodes reduced by whitespaces -->
            <xsl:text>"*[not(normalize-space(.))]" matches: </xsl:text>
            <xsl:for-each select="*[not(normalize-space(.))]">
                <xsl:value-of select="name()"/><xsl:text> </xsl:text>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
    
            <!-- combination -->
            <xsl:text>"*[not(normalize-space(.)) and not(*)]" matches: </xsl:text>
            <xsl:for-each select="*[not(normalize-space(.)) and not(*)]">
                <xsl:value-of select="name()"/><xsl:text> </xsl:text>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
    
        </xsl:template>
    </xsl:stylesheet>
    

    <强>输出:

    "*[not(*)]" matches: tag1 tag2 tag5 tag6 tag7 
    "*[not(node())]" matches: tag2 tag6 
    "*[not(text())]" matches: tag2 tag3 tag6 
    "*[not(normalize-space(.))]" matches: tag2 tag3 tag4 tag5 tag6 tag7 
    "*[not(normalize-space(.)) and not(*)]" matches: tag2 tag5 tag6 tag7 
    

    函数node()匹配可以通过child :: axis选择的任何节点类型:

    • 元素
    • 文本节点
    • 处理指令(PI)节点
    • 评论节点。

答案 1 :(得分:0)

  

要删除的代码(如果它们是空的)是:tag2, tag4

在XSLT中这很简单:

<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="tag2[not(node())] | tag4[not(node())]"/>

</xsl:stylesheet>