在python中有没有一种好的方法来获取XML的内部子集?

时间:2020-06-09 22:57:25

标签: python xml

我有一些xml,我想获取内部xml的子集 我已经查看了ElementTree的文档和示例,但尚未真正找到解决方案

鉴于下面的示例,有没有一种简单的方法可以实现这一目标? 原始xml:

    <a>
        <b1>not interested</b1>
        <b2 key="not interested at all">
            <c key="i want this">
                <d1> the good stuff</d1>
                <d2> more good stuff </d2>
                <d3>
                    <e1 key="good">still good stuff</e1>
                </d3>
            </c>
        </b2>
    </a>

而且我想提取一些内部xml,所以结果将是:

<c key="i want this">
    <d1> the good stuff</d1>
    <d2> more good stuff </d2>
    <d3>
        <e1 key="good">still good stuff</e1>
    </d3>
</c>

2 个答案:

答案 0 :(得分:0)

这可以通过lxml轻松完成:

import lxml.html as lh
data ="""[your html above]"""

doc = lh.fromstring(data)
target = doc.xpath('.//c')
print(lh.tostring(target[0]).decode())

输出是您的预期输出。

答案 1 :(得分:0)

以下是使用xml.etree.ElementTree模块和您在问题中提供的XML示例的解决方案。

请参阅下面的代码示例中的相应注释。

  1. 从源XML文本创建根元素。

    xml.etree.ElementTree.fromstring()函数解析提供的XML字符串并返回一个Element实例。

  2. 使用XPath查询来查找新的根元素。

    findall()函数从源Element对象返回匹配的Element对象的列表

    由于您要尝试为新的XML文档建立新的根目录,因此该查询必须设计为匹配源文档中的一个元素和一个元素,因此通过new_root提取[0]。 (在此处插入适当的错误处理!)

ElementTree模块的限制是XPath support,但这是查询字符串的细分:

.//c:搜索所有<c>元素

[@key='i want this']:过滤找到的<c>个元素,仅返回具有key属性与'i want this'匹配的元素

  1. 将新的根元素编码为Unicode字符串。

    xml.etree.ElementTree.tostring()函数将提供的Element及其子元素呈现为XML文本。之所以指定encoding="unicode",是因为默认编码返回了byte string

代码示例:

import xml.etree.ElementTree as ET

if __name__ == "__main__":
    # 0. Assign test XML text string.
    my_xml = '''<a>
        <b1>not interested</b1>
        <b2 key="not interested at all">
            <c key="i want this">
                <d1> the good stuff</d1>
                <d2> more good stuff </d2>
                <d3>
                    <e1 key="good">still good stuff</e1>
                </d3>
            </c>
        </b2>
    </a>'''
    # 1. Create root Element from the source XML text.
    root = ET.fromstring(my_xml)
    # 2. Use XPath query to locate the new root Element.
    new_root = root.findall(".//c[@key='i want this']")[0]
    # 3. Encode new root Element to a Unicode string.
    my_new_xml = ET.tostring(new_root, encoding="unicode")
    print(my_new_xml)