空文本节点如何处理?

时间:2018-09-19 17:35:39

标签: xml xslt textnode

如果我应用以下xslt

<xsl:stylesheet version="2.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="*">
        <xsl:copy><xsl:apply-templates/></xsl:copy>
    </xsl:template>

    <xsl:template match="b/*">
        <xsl:copy><xsl:apply-templates/></xsl:copy>
    </xsl:template>

    <xsl:template match="text()">text</xsl:template>

</xsl:stylesheet>

在以下xml上

<?xml version="1.0"?>

<a>
   <b></b>
</a>

输出为

<a>
    text
    <b></b>
    text
</a>

我没有得到什么:除元素b内的空文本节点外,所有元素之间的空文本节点都得到处理。对于a和b的子元素的处理方式,我看不出任何区别。

2 个答案:

答案 0 :(得分:2)

b元素内没有空的文本节点,它是一个完全没有子节点的空元素。另一方面,a元素具有三个子节点,第一个是带有空格(至少一个换行符和一些空格或制表符)的文本节点,第二个是b元素,第三个是带有空格(至少一个换行符)的文本节点。

通过显示的text输出的缩进,您从哪里得到的结果?在http://xsltransform.hikmatu.com/94hvTyG,我得到输出<a>text<b></b>text</a>

答案 1 :(得分:2)

实际上,至少在XSLT 2.0 / 3.0模型中,可以存在零长度的文本节点,但前提是该节点是无父的。尝试将其附加到父元素后,它就会消失。因此,如果您这样做:

<xsl:variable name="x" as="node()">
  <xsl:text/>
</xsl:variable>

然后count($x)返回1,$x instance of text()返回true,而string-length($x)返回0。但是当您这样做时

<xsl:variable name="e" as="node()">
   <xsl:copy-of select="$x"/>
</xsl:variable>

然后count($x)/child::node()返回0。这是由构造复杂内容的规则定义的(XSLT 3.0中的第5.7.1节,规则6)“序列中的零长度文本节点已删除。”

并且XDM数据模型定义了一个约束(3.1版本中的第6.7.1节规则1):“如果文本节点的父级不为空,则文本节点不得包含长度为零的字符串作为其内容。”

请注意,W3C规范始终使用“空”一词来指代没有成员的集合,而没有字符的字符串始终被称为“零长度”。在上面的示例中,$ x的长度为零,但不为空。

XPath 1.0 / XSLT 1.0中的情况有所不同。无父文本节点不能出现在1.0中,因此零长度文本节点将永远不存在。