1

过去我使用单独的转换删除了空标签,如下所示,但现在我必须在同一个 XSLT 2.0 转换中执行此操作。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*" />
    <xsl:template match="*[not(node()) and not(./@*)]"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

鉴于此 XML,我想从策略节点中删除所有空标签。XML 最大可达 40 MB 左右:

<?xml version="1.0" encoding="UTF-8"?>
<myroot>
    <data>
        <data1>abc</data1>
        <data2>123</data2>
    </data>
    <policy>
        <policydata1>Hello World!</policydata1>
        <policydata2/>
    </policy>
</myroot>

我的想法是使用 XSLT 2.0 我可以将与策略节点相关的转换输出保留在定义为“元素”的变量中,这样我就可以像 XML 一样对待它,然后遍历该变量以删除空标签:

    <xsl:variable name="completepolicy" as="element()">
       <policy>
         <policydata1>Hello World!</policydata1>
         <policydata2/>
       </policy>
   </xsl:variable>

如何在变量中合并标签删除而不影响我的转换中的其余模板的答案似乎让我无法理解。你能帮我解决可能很明显的问题吗?

注意我提出围绕“策略”输出的变量的原因是我已经声明了它,因为需要从转换中提取一些消息以在其他地方输出。

4

2 回答 2

1

只需使用原始转换,但替换

<xsl:template match="*[not(node()) and not(./@*)]"/>

<xsl:template match="policy/*[not(node()) and not(@*)]"/>
于 2012-08-09T16:13:51.637 回答
0

我不清楚为什么你不能简单地合并规则

<xsl:template match="*[not(node()) and not(./@*)]"/>

在您现有的样式表中,可能具有更高的优先级。我想这取决于其他模板规则在做什么。如果您需要空节点出现在绑定到 $completepolicy 的树中,然后想在处理的第二阶段删除它们,我会使用模式来做到这一点:模板规则适用于每个处理阶段的一种模式。

于 2012-08-09T20:57:49.917 回答