3
4

1 に答える 1

5

使用:

/*/a/preceding-sibling::node()
       [not(self::text()[not(normalize-space())])]
            [1]
              [self::a]

XSLT ベースの検証:

<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>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<r>
  <a>a1</a><a>a2</a>
   b
  <a>a3</a>
    <a>a4</a>
  <b/>
  <a>a5</a>
</r>

XPath 式が評価され、この評価によって選択されたノードが出力にコピーされます

<a>a1</a>
<a>a3</a>

更新

質問の XPath 式の何が問題になっていますか?

問題はここにあります

[not(text()) or normalize-space(.)='']

これは、コンテキスト ノードにテキスト ノードchildがないかどうかをテストします。

しかし、OP は、コンテキスト ノードテキスト ノードであるかどうかをテストしたいと考えています。

解決策:

上記を次のように置き換えます。

[not(self::text()) or normalize-space(.)='']

XSLT ベースの検証:

<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>

これで、この変換により、まさに必要な結果が得られます。

<a>a1</a>
<a>a3</a>
于 2012-12-26T20:07:13.677 に答える