问问题
2375 次
1 回答
5
Use:
/*/a/preceding-sibling::node()
[not(self::text()[not(normalize-space())])]
[1]
[self::a]
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/a
/preceding-sibling::node()
[not(self::text()[not(normalize-space())])]
[1]
[self::a]
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<r>
<a>a1</a><a>a2</a>
b
<a>a3</a>
<a>a4</a>
<b/>
<a>a5</a>
</r>
the XPath expression is evaluated and the nodes that are selected by this evaluation, are copied to the output:
<a>a1</a>
<a>a3</a>
Update:
What is wrong with the XPath expression in the question?
The problem is here:
[not(text()) or normalize-space(.)='']
This tests if the context node doesn't have a text node child.
But the OP wants to test if the context node is a text node.
Solution:
Replace the above with:
[not(self::text()) or normalize-space(.)='']
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*/a">
<xsl:copy-of select=
"preceding-sibling::*[1]
[name()='a']
[following-sibling::node()[1]
[not(self::text()) or normalize-space(.)='']
]"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
Now this transformation produces exactly the wanted result:
<a>a1</a>
<a>a3</a>
于 2012-12-26T20:07:13.677 回答