3

我有一个具有以下结构的 xml 文档。我正在编写一个转换,我想从节点 B 输出文本,但忽略元素 C 和文本节点“标题”。本质上,我想提取文本“文本在此处”并将其输出到一个新元素中,所有空格都已标准化。有人可以帮忙吗?以下是我迄今为止尝试过的。

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>

问题:元素之间的空白被保留,所以我得到这样的东西:

<d>

  Text goes here

</d>

我还尝试<xsl:value-of select="./text()"/>在解决方案 A 的模板中使用 value-of 语句 (),但这根本没有返回任何文本。声明有问题吗?

我应该提到我已经使用以下内容覆盖了默认的文本处理模板:<xsl:template match="text()" />

谢谢

4

3 回答 3

9

返回“nothing”的原因<xsl:value-of select="./text()"/>./text()它将返回一个由当前节点的所有直接子文本节点组成的节点集。value-ofa 节点集是其第一项的字符串值,在这种情况下,它是开始标签<B>和开始标签之间的纯空格文本节点<C>。这同样适用于下一个最明显的normalize-space(text()),因为它再次将节点集转换为字符串(第一个节点值),然后规范化该字符串中的空间。相反,您需要单独规范化每个子文本节点:

<d>
  <xsl:for-each select="text()">
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:for-each>
</d>

不过要注意的一件事是,如果您有类似的输入

<A>
  <B>
    <C>title</C>
     text goes here
    <C>subtitle</C>
     more text here
  </B>
</A>

然后你会得到输出

<d>text goes heremore text here</d>

字幕两侧的位之间没有空格。如果这是一个问题,您可以使用类似的技巧

<d>
  <xsl:for-each select="text()[normalize-space(.)]">
    <xsl:if test="position() &gt; 1"><xsl:text> </xsl:text></xsl:if>
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:for-each>
</d>

仅遍历那些包含非空白字符的文本节点子节点,并在除第一个之外的所有子节点之前添加一个空格。

<d>text goes here more text here</d>
于 2012-12-06T14:30:32.910 回答
0

我得到的最接近的是选择child//B/child::text()

轴将仅返回作为当前上下文节点的直接子节点的child文本节点,因此它不会匹配该title节点。

于 2012-12-06T14:12:12.953 回答
0

试试这个代码!

<copy-of>我没有使用模板覆盖!

  1. 我把B换成D..

  2. <C>从输出中掉线。这解决了一半的问题,因此<C>节点的文本不会出现在输出中。

  3. 我将 normalize-space 函数应用于所有文本节点..所以额外的空白将被擦除:)

这是代码:

  <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
      <xsl:template match="B">
        <d>
          <xsl:apply-templates select="node()"/>
        </d>
      </xsl:template>

      <xsl:template match="C"/>

      <xsl:template match="text()">
        <xsl:value-of select="normalize-space(.)"/>
      </xsl:template>
    </xsl:stylesheet>
于 2012-12-06T14:21:55.217 回答