我有一个具有以下结构的xml文档。我正在编写一个转换,其中我想从节点B输出文本,但忽略元素C和文本节点“ title”。本质上,我想提取文本“这里的文本”,并将其输出到一个标准化了所有空白的新元素中。有人可以帮忙吗?以下是到目前为止我尝试过的。
Input Doc
<A>
<B>
<C>title</C>
text goes here
</B>
</A>
Required output doc
<d>text goes here</d>
Solution A:
<xsl:template match="B">
<d>
<xsl:copy-of select="./text()"/>
</d>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
问题:元素之间的空白被保留了,所以我得到了这样的东西:
<d>
Text goes here
</d>
Run Code Online (Sandbox Code Playgroud)
我也尝试使用value-of语句(<xsl:value-of select="./text()"/>在解决方案A的模板中),但这根本不返回任何文本。声明有问题吗?
我应该提到,我已经使用以下方法覆盖了默认的文本处理模板: <xsl:template match="text()" />
谢谢
<xsl:value-of select="./text()"/>返回“ nothing” 的原因是./text()将返回一个由当前节点的所有直接子文本节点组成的节点集。的value-of一节点集合是其的字符串值第一项,在这种情况下是所述开口之间的唯一的空白文本节点<B>和开口<C>标签。倒数第二个同样适用,normalize-space(text())因为这再次将节点集转换为字符串(第一个节点值),然后对该字符串中的空间进行归一化。相反,您需要分别标准化每个子文本节点:
<d>
<xsl:for-each select="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
</d>
Run Code Online (Sandbox Code Playgroud)
关于这一点要注意的一件事是,如果您输入类似
<A>
<B>
<C>title</C>
text goes here
<C>subtitle</C>
more text here
</B>
</A>
Run Code Online (Sandbox Code Playgroud)
那么您将获得输出
<d>text goes heremore text here</d>
Run Code Online (Sandbox Code Playgroud)
字幕两侧的位之间没有空格。如果这是一个问题,您可以使用类似的技巧
<d>
<xsl:for-each select="text()[normalize-space(.)]">
<xsl:if test="position() > 1"><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
</d>
Run Code Online (Sandbox Code Playgroud)
仅对包含非空格字符的那些文本节点子项进行迭代,并在除第一个以外的所有其他字符之前添加一个空格。
<d>text goes here more text here</d>
Run Code Online (Sandbox Code Playgroud)