如何使用xslt删除空标签和换行符?

时间:2017-11-15 19:45:43

标签: xslt

我想通过XSLT从XML文件中删除空标签和换行符。

标准1: 换行符只能在文本节点中删除,即XML应保持缩进。

标准2: 应该适用于任何操作系统。

标准3: 如果可能,XML将不会有任何其他更改。

示例XML将是:

<?xml version="1.0" encoding="UTF-8"?>
<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <tag1>22</tag1>
    <tag2>33</tag2>
    <tag3/>
    <minimalValue/>
    <maximalValue/>
    <minimalFee/>
    <maximalFee/>
    <tag4>This is text with a
        line break.
    </tag4>
</Container>

结果应为:

<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <tag1>22</tag1>
   <tag2>33</tag2>
   <tag4>This is text with a line break.</tag4>
</Container>

2 个答案:

答案 0 :(得分:1)

要省略初始XML声明,您应该使用omit-xml-declaration xsl:output中的属性。

缩进使用indent="yes"

要删除空标记,您需要元素match="*")的模板, 但是谓词要求此元素仅具有非空白 内容([normalize-space()])。 由于没有空元素的模板,因此不会复制它们。

要删除换行符,您需要text()个节点的模板, 复制规范化的内容。

总而言之,您可以使用以下脚本,稍微简洁一些 比其他提案:

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

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

  <xsl:template match="text()">
    <xsl:value-of select="normalize-space()"/>
  </xsl:template>
</xsl:stylesheet>

请注意,我在2个地方添加了|@*来处理属性节点, 就像在身份模板中一样。 但由于您的源XML不包含任何属性节点, 即使没有这些补充,你也可以做到。

答案 1 :(得分:0)

我不确定这是否是最好的方法。但我已通过以下模板实现了上述目标:

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

    <xsl:template match="child::node()[not(self::text())]|@*">
        <xsl:if test="normalize-space(string(.)) != ''">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:if>
    </xsl:template>

    <xsl:template match="text()">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>
</xsl:stylesheet>