Xml 表达式来标识后面没有内容的最后一个元素

Xml 表达式来标识后面没有内容的最后一个元素,xml,xslt,xpath,Xml,Xslt,Xpath,我有两种不同的情况 案例A <cell> text here and there <break/> text here and there <break/> </cell> 我几乎可以完成这项工作,但我需要排除那些有文字的人 有什么建议吗?使用如下表达式: break[position() = last() and not(following-sibling::text()[normalize-space(.) != ''

我有两种不同的情况

案例A

<cell>
   text here and there
   <break/>
   text here and there
   <break/>
</cell>
我几乎可以完成这项工作,但我需要排除那些有文字的人


有什么建议吗?

使用如下表达式:

break[position() = last() and not(following-sibling::text()[normalize-space(.) != ''])]
简而言之,它的意思是:

选择上下文中的最后一个
break
元素,但前提是该元素后面没有文本节点,而不是只包含空格的文本节点

正如@keshlam所建议的,最后一个条件是必需的,因为换行符也是文本节点。但是,如果对只包含空格的文本节点应用了
normalize-space()
,则该节点将等于

假设以下输入:

输入1

<cell>
   text here and there
   <break/>
   text here and there
   <break type="wrong"/>
   text here and there
</cell>

这里和那里的文本
这里和那里的文本
这里和那里的文本
样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="break[position() = last() and not(following-sibling::text()[normalize-space(.) != ''])]">
        <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

将(正确地)不产生任何输出。另一方面,

输入2

<cell>
   text here and there
   <break/>
   text here and there
   <break type="correct"/>
</cell>
<?xml version="1.0" encoding="utf-8"?>
<break type="correct"/>

这里和那里的文本
这里和那里的文本
收益率:

输出2

<cell>
   text here and there
   <break/>
   text here and there
   <break type="correct"/>
</cell>
<?xml version="1.0" encoding="utf-8"?>
<break type="correct"/>

使用如下表达式:

break[position() = last() and not(following-sibling::text()[normalize-space(.) != ''])]
简而言之,它的意思是:

选择上下文中的最后一个
break
元素,但前提是该元素后面没有文本节点,而不是只包含空格的文本节点

正如@keshlam所建议的,最后一个条件是必需的,因为换行符也是文本节点。但是,如果对只包含空格的文本节点应用了
normalize-space()
,则该节点将等于

假设以下输入:

输入1

<cell>
   text here and there
   <break/>
   text here and there
   <break type="wrong"/>
   text here and there
</cell>

这里和那里的文本
这里和那里的文本
这里和那里的文本
样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="break[position() = last() and not(following-sibling::text()[normalize-space(.) != ''])]">
        <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

将(正确地)不产生任何输出。另一方面,

输入2

<cell>
   text here and there
   <break/>
   text here and there
   <break type="correct"/>
</cell>
<?xml version="1.0" encoding="utf-8"?>
<break type="correct"/>

这里和那里的文本
这里和那里的文本
收益率:

输出2

<cell>
   text here and there
   <break/>
   text here and there
   <break type="correct"/>
</cell>
<?xml version="1.0" encoding="utf-8"?>
<break type="correct"/>

试试:

尝试:


这可能不太管用,因为事实上,在这两种情况下,sib后面都有一个文本:换行符空格。@keshlam你说得对,谢谢你发现了这一点!我编辑了我的答案来解释这一点。这可能不太管用,因为事实上,在这两种情况下,sib后面都有一个文本:换行空白。@keshlam你说得对,谢谢你发现了这一点!我编辑了我的答案来解释这一点。如果OP打算选择一个
break
,如果它是父元素关闭前的最后一个节点,那么它就起作用了。但是如果OP打算选择的最后一个break节点后面没有文本节点,但后面可能有另一个元素,则不起作用。@MathiasMüller是真的,但OP说“我有两种不同的情况”。我已经超越了这一点,没有满足于我原来的
break[not(跟随兄弟姐妹::text())]
,尽管keshlam发表了评论,但这本可以很好地工作。你最初的表达(和我的一样)只有在输入XML中没有换行符和空格的情况下才有效——我对此表示怀疑。但我同意,也许没有必要推广解决方案。@MathiasMüller如果样式表包含
,那么它仍然有效。我只发布XPath的错误。+1同意——甚至比我过于复杂的XPath。如果OP想要选择一个
break
,如果它是父元素关闭前的最后一个节点,则可以使用它,但如果他们想要选择的最后一个break节点后面没有文本节点,但后面可能有另一个元素,则不能使用它。@MathiasMüller True,但OP说“我有两种不同的情况“。我已经超越了这一点,没有满足于我原来的
break[not(following sibling::text())]
,尽管keshlam发表了评论,但这本可以很好地工作。只有在输入XML中没有换行符和空格的情况下,您的原始表达式(和我的一样)才会工作,我对此表示怀疑。”。但是我同意,也许没有必要推广这个解决方案。@MathiasMüller尽管如此,如果样式表包含
,它还是可以工作的。我只发布XPath的错误。+1同意,这比我过于复杂的XPath更加优雅。