如果我应用以下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的子元素的处理方式,我看不出任何区别。
答案 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中,因此零长度文本节点将永远不存在。