首页 > 解决方案 > 在lxml Python 3中如何递归地所有链接的ID

问题描述

我有一个这样的xml:

<library>
    <content content-id="title001">
        <content-links>
            <content-link content-id="Number1" />
            <content-link content-id="Number2" />
        </content-links>
    </content>
    <content content-id="title002">
        <content-links>
            <content-link content-id="Number3" />
        </content-links>
    </content>
    <content content-id="Number1">
        <content-links>
            <content-link content-id="Number1b" />
        </content-links>
    </content
</library>

我需要获取链接到特定内容 ID 标题的所有内容 ID。例如,对于这种情况,我需要为 title001 链接的所有 id(我可能需要更多的标题,所以这将是需要找到的标题列表)。所有这些 id 都被添加到一个看起来像这样的列表中: [title001, Number1, Number2, Number1b]

所以我想我需要递归检查每个内容,然后从内容链接中获取内容 ID 以转到下一个内容,并将所有内容链接签入到下一个内容,直到完全读取 xml .

我无法找到对此的递归解决方案。

为此添加到目前为止我得到的代码:

from lxml import etree as et
def get_ids(content):
    """
    """
    content_links = content.findall('content-links/content-link')
    print(content_links)
    if content_links:
        for content_link in content_links:
            print(content_link,content_link.get('content-id'))
            cl = content_link.get('content-id')
            cont = x.find(f'content[@id="{cl}"]')
            if cont is not None:
                get_ids(cont)

if __name__ == '__main__':
    """
    """
    x = et.fromstring(xml)
    ids = ['title001']
    for id in ids:
        content = x.find(f'content[@id="{content-id}"]')
        get_ids(content)

标签: python-3.xrecursionxml-parsinglxml

解决方案


试试下面的代码:

from lxml import etree as et

parser = et.XMLParser(remove_blank_text=True)
tree = et.parse('Input.xml', parser)
root = tree.getroot()
cidList = ['title001']  # Your source list
cidDct = { x: 0 for x in cidList }
for elem in root.iter('content'):
    cid = elem.attrib.get('content-id', '')
    # print(f'X  {elem.tag:15}  cid:{cid}')
    if cid in cidDct.keys():
        # print(f'** Found:  {cid}')
        for elem2 in elem.iter():
            if elem2 is not elem:
                cid2 = elem2.attrib.get('content-id', '')
                # print(f'XX {elem2.tag:15}  cid:{cid2}')
                if len(cid2) > 0:
                    # print(f'** Add:  {cid2}')
                    cidDct[cid2] = 0

对于测试,您可以取消注释上面的打印输出。

现在,当您打印时list(cidDct.keys()),您将获得所需的id

['title001', 'Number1', 'Number2', 'Number1b']

推荐阅读