簡體   English   中英

如何使用Python從XML中刪除元素

[英]How to remove elements from XML using Python

我厭倦了XML和Python。 任務很簡單,但到目前為止我無法解決它並花了很長時間。 我來這里是為了建議如何用幾行來解決它。

感謝您遍歷樹的任何幫助。 我總是得到太多或太少的元素。 元素可以無限制地嵌套。 舉個例子就是一個例子。 我會接受任何解決方案,而不是挑剔dom,minidom,sax,等等......

我有一個類似於這個的XML文件:

<root>
    <elm>
        <elm>Common content</elm>

        <elm xmlns="http://example.org/ns">
            <elm lang="en">Content EN</elm>
            <elm lang="cs">žluťoučký koníček</elm>
        </elm>

        <elm xml:id="abc123">Common content</elm>

        <elm lang="en">Content EN</elm>
        <elm lang="cs">Content CS</elm>

        <elm lang="en">
            <elm>Content EN</elm>
            <elm>Content EN</elm>
        </elm>

        <elm lang="cs">
            <elm>Content CS</elm>
            <elm>Content CS</elm>
        </elm>
    </elm>
</root>

我需要的 - 解析XML並編寫一個新文件。 新文件應包含給定語言的所有元素和沒有lang屬性的元素。

對於“cs”語言,輸出文件應包含以下內容:

<root>
    <elm>
        <elm>Common content</elm>

        <elm xmlns="http://example.org/ns">
            <elm lang="cs">žluťoučký koníček</elm>
        </elm>

        <elm xml:id="abc123">Common content</elm>

        <elm lang="cs">Content CS</elm>

        <elm lang="cs">
            <elm>Content CS</elm>
            <elm>Content CS</elm>
        </elm>
    </elm>
</root>

如果你可以在新文件中省略lang屬性,那就更好了。 但它並不重要。

UPDATE1:添加了unicode字符和名稱空間屬性。

UPDATE2:使用Python 2.5,首選標准庫。

使用lxml

import lxml.etree as le

with open('doc.xml','r') as f:
    doc=le.parse(f)
    for elem in doc.xpath('//*[attribute::lang]'):
        if elem.attrib['lang']=='en':
            elem.attrib.pop('lang')
        else:
            parent=elem.getparent()
            parent.remove(elem)
    print(le.tostring(doc))

產量

<root>
    <elm>Common content</elm>

    <elm>
        <elm>Content EN</elm>
        </elm>

    <elm>Common content</elm>

    <elm>Content EN</elm>
    <elm>
        <elm>Content EN</elm>
        <elm>Content EN</elm>
    </elm>

    </root>

我不確定如何最好地刪除lang屬性,但是這里有一些代碼可以執行其他更改(Python 2.7;對於2.5或2.6,使用getIterator而不是iter ),假設當您刪除元素時,您也總是希望刪除該元素中包含的所有內容。

此代碼只是將結果打印到標准輸出(您可以根據需要重定向它,當然,或直接將其寫入某個新文件,依此類推):

import sys
from xml.etree import cElementTree as et

def picklang(path, lang='en'):
    tr = et.parse(path)
    for element in tr.iter():
        for subelement in element:
            la = subelement.get('lang')
            if la is not None and la != lang:
                element.remove(subelement)
    return tr

if __name__ == '__main__':
    tr = picklang('la.xml')
    tr.write(sys.stdout)
    print

la.xml為例,這寫道

<root>
    <elm>Common content</elm>

    <elm>
        <elm lang="en">Content EN</elm>
        </elm>

    <elm>Common content</elm>

    <elm lang="en">Content EN</elm>
    <elm lang="en">
        <elm>Content EN</elm>
        <elm>Content EN</elm>
    </elm>

    </root>

更新@Alex Martelli的代碼,以刪除元素列表更新到位的錯誤。 如果輸入稍微復雜,上述解決方案將給出錯誤的答案。

import sys
from xml.etree import cElementTree as et

def picklang(path, lang='en'):
    tr = et.parse(path)
    for element in tr.iter():
        for subelement in element[:]:
            la = subelement.get('lang')

            if la is not None and la != lang:
                element.remove(subelement)
    return tr

if __name__ == '__main__':
    tr = picklang('la.xml')
    tr.write(sys.stdout)
    print

第7行for subelement in element:代碼for subelement in element:更改for subelement in element[:]:因為在迭代時更新列表是不正確的。

此代碼迭代元素列表的副本,並在原始元素列表中的lang!=“en”時刪除元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM