简体   繁体   English

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

[英]Removing a specified set of empty tags from in XML using Java or XSLT

I have a requirement to remove a specified set of tags from an XML if they are empty. 如果它们为空,我需要从XML中删除一组指定的标签。

For eg: 例如:

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

In this, the tags to remove (if they are empty) are : 在此,要删除的标签(如果为空)为:

tag2, tag4

Expected Result : 预期结果 :

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

What is the best way to achieve this using plain Java or XSLT? 使用纯Java或XSLT实现此目标的最佳方法是什么? Other than this, do we have a 3rd party library which can be used for the same thing? 除此之外,我们还有一个可以用于同一事物的第三方库吗?

Regards, Anoop 问候,阿努普

tags from an XML if they are empty. XML中的广告代码(如果为空)。

What is empty? 什么是空的? There are different possible definitions of "empty": “空”有不同的可能定义:

  1. no childs 没有孩子
  2. no text 没有文字
  3. no whitespace textnodes (eg ' ', CR, NL, #x20, #x9, #xD or #xA. ) 没有空白文本节点(例如'',CR,NL, #x20,#x9,#xD或#xA。
  4. combinations of above 以上组合

Test-Study Input: 测试研究输入:

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

    </tag7>
</root>

Test-Study Transformation: 测试研究转换:

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

Output: 输出:

"*[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 

Function node() matches any node type that can be selected via the child:: axis: 函数node()与可以通过child ::轴选择的任何节点类型匹配:

  • element 元件
  • text-node 文本节点
  • processing-instruction (PI) node 处理指令(PI)节点
  • comment node. 评论节点。

the tags to remove (if they are empty) are : tag2, tag4 要删除的标签(如果为空)为: tag2, tag4

This is rather trivial to do in XSLT: 这在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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM