2016-05-25 7 views
0

私は次のようなXMLドキュメントがあります。XPathを使用して、次の特定のXMLノードを選択する方法は?

<Objects> 
    <object distName="a/b"> </object> 
    <object distName="a/b/c1"> </object> 
    <object distName="a/b/c4/d/e"> </object> 
    <object distName="a/b/c2"> </object> 
    <object distName="a/b/c6/d"> </object> 
</Objects> 

をそして私は「C」+数で終わるパスを持っているすべてのノードを選択する必要があります。以下のように: "/B/C1" と "/B/C2" が、好きではない "/B/C6/D"、また "/B/C4/D/E" 。

私は次のことをしようとした場合:

 `cNodes = xmlDoc.xpath("//object[contains(@path, `a/b/c`)]")` 

その後、これは私が必要とするものではありません "A/B/C6/D" と "A/B/C4/D/E" が含まれます。

のコードを1行または2行で記述する方法があります。です。私は、ループのようなものでそれをやり遂げることができ、そのようなことはしたくない、ということです。実際のXML文書は何千ものノードであるからです。

PS:Pythonの2.7、lxmlの

+0

いいえ、パスは属性に過ぎません。それは内容とは関係ありません。 – AhmedWas

+0

@JeffMercado名前を 'path'から' distName'に変更しました。私は単に例を挙げているからです。私が持っているXML文書とまったく同じではありません。 – AhmedWas

+0

@JeffMercado申し訳ありません、私の間違いです。私は編集します。 – AhmedWas

答えて

1

残念ながら、XPath 1.0を使用してパターンに一致する条件を表現することはあまり簡単ではありません。しかし、あなたが探しているものについてある種の仮定をすることができれば、あなたはそのような質問を作ることができます。

//object[starts-with(@distName, 'a/b/c') and substring-after(@distName, 'a/b/c') >= 0] 

distName属性がa/b/cで始まる場合、我々は最初にチェックしている、それを断ち切ります。その後、その文字列の後のすべてが何番かの場合。あなたのニーズに応じて、これで十分かもしれません。

+0

完璧な男、魅力的な作品:) – AhmedWas

1

私はこれは、XPathバージョンlxmlサポートしていることである純粋のXPath 1.0を使用して行うことができない恐れています。

代わりに、例えば、リストの内包表記を使用して1行で、すべての最後の分割結果を得る、/して属性を分割しようとすると、それはcで始まるかどうかを確認することができます

>>> raw = '''<Objects> 
... <object distName="a/b"> </object> 
... <object distName="a/b/c1"> </object> 
... <object distName="a/b/c4/d/e"> </object> 
... <object distName="a/b/c2"> </object> 
... <object distName="a/b/c6/d"> </object> 
... </Objects>''' 
... 
>>> from lxml import etree 
>>> xmlDoc = etree.fromstring(raw) 
>>> cNodes = xmlDoc.xpath("//object[contains(@path, 'a/b/c')]") 
>>> result = [etree.tostring(n) for n in cNodes if n.attrib["distName"].split('/')[-1].startswith("c")] 
>>> print result 
['<object distName="a/b/c1"> </object>\n ', '<object distName="a/b/c2"> </object>\n '] 
+0

これらのcノードは、実際のXMLファイル内の他のノードの親であるということです。そして、私はノード自体の選択に気をつけます。しかし、ループを通過する以外の方法はないように見えます。とにかく、答えのおかげで:) – AhmedWas

+0

いいえ、解決策があるように見えます。受け入れられた答えはちょうど私が必要としたものです。 – AhmedWas

関連する問題