2

Xpathを使用して、少なくとも類似/等しい兄弟ノードを持つノードのみを検索するにはどうすればよいですか?

例えば:

<root>
  <parent>
    <node>...</node>
    <node_unique>...</node_unique>
    <node>...</node>
    <another_one>...</another_one>
    <another_one>...</another_one>
  </parent>
</root>

この例では、xpath shold selectのみ<node>であり<another_one>、複数回表示されているためです。

私はこれに対する解決策を何時間も成功せずに見つけようとしていました(今ではXPathでは不可能だと思います...)。

4

1 に答える 1

6

これらは、単一のXPath 1.0式で選択することはできません(XPath 1.0には範囲変数がないため)。

考えられる解決策の1つは、すべての要素を選択し、その/*/*/*要素を使用して各要素の名前を取得し、name()評価することです/*/*/*[name() = $currentName][2](ここで$currentName、取得した名前に置き換える必要があります。最後の式で要素を選択した場合、はcurrentName名前です。これは少なくとも2回発生するため、その要素を保持します。すべての要素とその名前を使用して保持します。補助的な手順として、名前(および選択した要素)をハッシュテーブルに配置することで重複させることができます。

Xpath 2.0では、単一のXPath式を使用して、同じ名前の兄弟が少なくとも1人いる、特定の親のすべての子を選択するのは簡単です

/*/*/*
   [name() = following-sibling::*/name()
  and
    not(name() = preceding-sibling::*/name())
   ]

はるかにコンパクトな表現

/*/*/*[index-of(/*/*/*/name(), name())[2]]

XSLT 2.0ベースの検証

<xsl:stylesheet version="2.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=
  "/*/*/*[index-of(/*/*/*/name(), name())[2]]"/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<root>
  <parent>
    <node>...</node>
    <node_unique>...</node_unique>
    <node>...</node>
    <another_one>...</another_one>
    <another_one>...</another_one>
  </parent>
</root>

上記のXPath式が評価され、この評価要素から選択されたものが出力にコピーされます

<node>...</node>
<another_one>...</another_one>

:関連する質問/回答については、こちらをご覧ください

于 2012-09-23T04:14:24.073 に答える