XSLT - 检测元素之间的文本

时间:2017-02-07 21:34:47

标签: xslt xpath

我正在进行转换,将相同类型的连续元素包装到单个元素中,但前提是节点之间没有文本。

例如:

<foo>ABC</foo><foo>DEF</foo> <foo>GHI</foo>
  <foo>JKL</foo>

应转换为:

<bar>
  <foo>ABC</foo>
  <foo>DEF</foo>
  <foo>GHI</foo>
  <foo>JKL</foo>
</bar>

无论是空格还是返回,都应忽略空格。任何其他文本都应表明应该包装的内容的结束。例如:

<foo>ABC</foo><foo>DEF</foo> some text in between <foo>GHI</foo>
  <foo>JKL</foo>

应转换为:

<bar>
  <foo>ABC</foo>
  <foo>DEF</foo>
</bar> some text in between 
<bar>
  <foo>GHI</foo>
  <foo>JKL</foo>
</bar>

我尝试使用

选择<foo>元素
foo[following-sibling::node()[1][normalize-space()='']]

但这并没有找到<foo>元素之间存在空格的情况。 (完整模板匹配中还有其他标准,但这是我预期无效的部分。

我编写了一个测试转换来输出在元素后面的文本上使用normalize-space函数的值,并为元素之间有空格的行输出单个空格。但是,如果我查询:

foo[following-sibling::node()[1][normalize-space()=' ']]

它找不到那些元素。所以,我完全糊涂了 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

[normalize-space()=''][not(normalize-space())]似乎不起作用的问题是因为在几个地方都有不间断的空格而不是常规空格。我更新了模板匹配以使用[not(normalize-space(translate(.,'&#160;', ' ')))]并且它有效。

答案 1 :(得分:0)

假设您使用XSLT 2.0

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="*[foo]">
        <xsl:copy>
            <xsl:for-each-group select="node()" group-adjacent="boolean(self::foo | self::text()[not(normalize-space())])">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <bar>
                            <xsl:apply-templates select="current-group()"/>
                        </bar>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:transform>

http://xsltransform.net/ncntCSS