如何处理空文本节点?

How are empty text-nodes processed?

如果我应用以下 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 的子元素的处理方式有什么不同。

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

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

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

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

然后 count($x) returns 1,$x instance of text() returns true,并且 string-length($x) returns 0。但是当你做

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

then count($x)/child::node() returns 0。这由构造复杂内容的规则定义(XSLT 3.0 中的§5.7.1,规则 6)"Zero-length text nodes within the sequence are removed."

并且XDM数据模型定义了一个约束条件(3.1版本中§6.7.1规则1):"If the parent of a text node is not empty, the Text Node must not contain the zero-length string as its content."

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

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