2016-10-19 10 views
1

はあなたのような内容でlmxl.etree要素があるとします。lxmlを使用してドキュメントのサブセットを作成する方法は?

<element1> 
    <subelement1>blabla</subelement1> 
</element1> 

方法あります:

<root> 
    <element1> 
     <subelement1>blabla</subelement1> 
    </element1> 
    <element2> 
     <subelement2>blibli</sublement2> 
    </element2> 
</root> 

私のようなものをレンダリングする要素が見つからまたはXPathの方法は何かを得るために使用することができます

<root> 
    <element1> 
     <subelement1>blabla</subelement1> 
    </element1> 
</root> 

関心の要素を加えたdocumまでのすべてのそれの先祖すなわち:取得するためのシンプルな根源?

+0

あなたが選択した要素のすべての先祖をしたいですか?それらは取り除かれるべきですか、異なるレベルの兄弟はどうでしょうか?あなたの例はそれをはっきりさせません。 – audiodude

+0

はい、それらも取り除かれるべきです..結果のサブセットは選択された要素でなければなりません+それは先祖が "空になりました" –

+0

私は間違っていると証明したいと思いますが、あなたは*シンプルな方法を見つけるつもりはないと思いますこれは、doc_root.strip_everything_but_child_by_xpath( 'some/xpath/element1')のように行います。要素を見つけた場所に基づいてDOMを歩かなければならず、手動でノードを削除/削除する必要があります。 – audiodude

答えて

2

iterancestors() parent iteratorを使用して回避策の種類「これまでの実際の生活の中でそれを使用しないでください」、私は組み込みのそれのために何かがあるかわからないが、ここで恐ろしいです:

from lxml import etree as ET 

data = """<root> 
    <element1> 
     <subelement1>blabla</subelement1> 
    </element1> 
    <element2> 
     <subelement2>blibli</subelement2> 
    </element2> 
</root>""" 


root = ET.fromstring(data) 
element = root.find(".//subelement1") 

result = ET.tostring(element) 
for node in element.iterancestors(): 
    result = "<{name}>{text}</{name}>".format(name=node.tag, text=result) 

print(ET.tostring(ET.fromstring(result), pretty_print=True)) 

プリント:

<root> 
    <element1> 
    <subelement1>blabla</subelement1> 
    </element1> 
</root> 
+0

私は、エレガントで組み込みのソリューションがあるかどうかを確認するために質問を投稿しました。私はあなたの答えに似たようなことをやってしまった、なぜそれがとてもひどいのか分からない。確かに非常にエレガントではないが、私はそれが動作すると思います –

+0

@ B-Kええ、それは自己批判のちょうど良い量でした:) – alecxe

+0

私は文字列としてこれを構築することはややひどいと思います。 'lxml.builder.E'では、文字列の書式設定によってXMLを構築することなくこれを行うことが可能です。 – BlackJack

1

次のコードは、任意のsubelement1子孫を持っていないとsubelement1命名されていない要素を削除します。

from lxml import etree 

tree = etree.parse("input.xml") # First XML document in question 

for elem in tree.iter(): 
    if elem.xpath("not(.//subelement1)") and not(elem.tag == "subelement1"): 
     if elem.getparent() is not None: 
      elem.getparent().remove(elem) 

print etree.tostring(tree) 

出力:

<root> 
    <element1> 
    <subelement1>blabla</subelement1> 
    </element1> 
    </root> 
関連する問題