2012-02-25 7 views
1

私はすべての<set>erase</set>の要素を選択しようとしているように、2つ以上の要素が階層に<set>erase</set>を持っている場合ということ:にのみ要素(例<b><d>両方が<set>erase</set>を持っています)親ノード名を選択する必要があります(この場合は<b>)。以下XPathクエリは、基準に基づいて子孫を無視して、すべての要素を選択するには

サンプルXML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<a> 
    <b> 
     <set>erase</set> 
     <d> 
      <set>erase</set> 
     </d> 
    </b> 

    <c> 
     <x></x> 
    </c> 

    <e> 
     <y> 
      <set>erase</set> 
      <q></q> 
     </y> 
     <z> 
      <p> 
       <set>erase</set> 
      </p> 
     </z> 
    </e> 
</a> 

私はquery = //set[contains(.,'erase')]を使用する場合、私は結果セットにnodesList b,d,y,pのすべて<set>erase</set>を取得します。

<set>erase</set>b,y、およびpを選択するために、クエリのフレーミングに助けが必要です。ここで

+0

私はあなたの要件が明確ではないと思います。あなたが描写した内容に基づいて、なぜ「a」が選択されないのでしょうか? –

+0

@ lwburk:申し訳ありませんが悪いです。私が与えたサンプルXMLを修正しました。 – user1207560

+0

要素値に基づいてancesterノードを取得するための[Xpathクエリ]の重複可能性(http://stackoverflow.com/questions/9271001/xpath-query-to-get-the-ancester-nodes-based-on-element-値) –

答えて

1

は同じソリューション次のとおりです。

まさに希望の要素を選択一つのXPath式がです:

  //*[set[. = 'erase' and not(node()[2])] 
      and 
       not(ancestor::* 
        [set 
         [. = 'erase' and not(node()[2])] 
        ] 
       ) 
       ] 

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="/"> 
      <xsl:for-each select= 
      "//*[set[. = 'erase' and not(node()[2])] 
       and 
        not(ancestor::* 
         [set 
          [. = 'erase' and not(node()[2])] 
         ] 
        ) 
        ]"> 

       <xsl:value-of select="name()"/> 
       <xsl:text>&#xA;</xsl:text> 
      </xsl:for-each> 
     </xsl:template> 
</xsl:stylesheet> 

この変換が提供されるXML文書に印加された場合:

<a> 
    <b> 
     <set>erase</set> 
     <d> 
      <set>erase</set> 
     </d> 
    </b> 
    <c> 
     <x></x> 
    </c> 
    <e> 
     <y> 
      <set>erase</set> 
      <q></q> 
     </y> 
     <z> 
      <p> 
       <set>erase</set> 
      </p> 
     </z> 
    </e> 
</a> 

含まれるXPath式を評価し、選択された要素の名前が出力される - 正しく予想通り:

b 
y 
p 

上記の要素の子をset個選択する必要がある場合は、上記のXPath式を/set

と追加してください再び
  //*[set[. = 'erase' and not(node()[2])] 
      and 
       not(ancestor::* 
        [set 
         [. = 'erase' and not(node()[2])] 
        ] 
       ) 
       ] 
       /set 

、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="/"> 
      <xsl:copy-of select= 
      "//*[set[. = 'erase' and not(node()[2])] 
       and 
        not(ancestor::* 
         [set 
          [. = 'erase' and not(node()[2])] 
         ] 
        ) 
        ] 
        /set 
        "/> 
     </xsl:template> 
</xsl:stylesheet> 

この変換は、ちょうど出力に、上記XPath式とコピーを評価し、正しく選択された3つのset要素

<set>erase</set> 
<set>erase</set> 
<set>erase</set> 
+0

私はを返すところで2番目の部分を欲しかった。これの背後にある理由は、JXPathを使って '消去'を持っているへのポインタを返すためです。 – user1207560

関連する問題