我构建了一个文本字符串,用于连接XML文件集合中的所有文本,使用:
<xsl:variable name="text-accumulated">
<xsl:for-each select="collection($collection-string)">
<xsl:copy-of select="//concat(text()[1], ' ')"/>
</xsl:for-each>
</xsl:variable>
注意:连接空间会阻止单词在某些回车(或换行符)周围合并。
结果
这对我有用。但我总是对使用//
持谨慎态度。
我也知道copy-of
完成深层复制的结果有时会让您大吃一惊。我使用了value-of
并收到了相同的结果。
有没有更好的方法来合并文件集合中的所有文本?
是否存在我应该使用的内置函数(IRT,Saxon 9.5)?
value-of
比copy-of
更好吗?
答案 0 :(得分:0)
<xsl:copy-of select="//concat(text()[1], ' ')"/>
此指令实际上不会复制XML文档的完整文本!
以下是一个例子:
<a>
<b>X1<c>Y</c>X2</b>
</a>
当使用以下转换处理上述XML文档时(其中仅包含来自提供的代码的XSLT指令):
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:copy-of select="//concat(text()[1], ' ')"/>
</xsl:template>
</xsl:stylesheet>
结果是:
X1 Y
如我们所见,输出中不存在字符串“X2
”。
另一个问题是,无法确定在任何两个文本节点之间添加了哪些空格作为分隔符。
换句话说,生成的输出并不完全是XML文档的文本节点的串联。
如果您不关心后一个问题,一个正确的XPath 2.0表达式使用空格作为分隔符连接文档中的所有文本节点:
//string-join(text(), ' ')
通过此更正,您提供的代码变为:
<xsl:variable name="text-accumulated">
<xsl:for-each select="collection($collection-string)">
<xsl:copy-of select="//string-join(text(), ' ')"/>
</xsl:for-each>
</xsl:variable>
value-of
比copy-of
更好吗?
比较这两个XSLT指令中的哪一个“更好”是不正确的,因为它们服务于不同的目标。
<xsl:value-of>
生成单个文本节点,其字符串值是所选项的字符串值的串联(如果指定了separator
属性,则可能用分隔符字符串分隔。
另一方面,
<xsl:copy-of>
生成一系列节点和/或原子值的副本,每个新节点递归地包含原始节点的所有子节点,属性和(默认情况下)名称空间的副本。
很明显,这两条指令不可相互替换,每条指令都可用于解决不同的问题。
这对我有用。但我总是对使用
持谨慎态度//
可以使用模式而不是绝对表达式。在你的情况下像这样:
<xsl:variable name="text-accumulated">
<xsl:apply-templates select="collection($collection-string)" mode="mergeText"/>
</xsl:variable>
<xsl:template match="text()" mode="mergeText">
<xsl:value-of select="concat(., ' ')"/>
</xsl:template>