如何处理空文本节点?
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 中不会出现无父文本节点,因此永远不会存在零长度文本节点。
如果我应用以下 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 中不会出现无父文本节点,因此永远不会存在零长度文本节点。