【问题标题】:parsing parent/children relationship of XML elements解析 XML 元素的父/子关系
【发布时间】:2014-09-21 13:22:50
【问题描述】:

给定以下 XML(ant build xml):

    <project name="pj1">
        <target name="t1">
            ...
            <antcall target="t2"/>
            <a>
                <antcall target="t4"/>
            </a>
            ...
        </target>
        <target name="t2">
            ...
            <antcall target="t3"/>
            ...
        </target>
        <target name="t3">
            ...
            ...
        </target>
        <target name="t4">
            ...
            <antcall target="t2"/>
            ...
        </target>
        <target name="t5">
            ...
            ...
        </target>
    </project>

我想显示目标元素的父/子关系如下(如果目标嵌套在另一个目标中,则不将目标显示为第一级元素)

t1
    t2
        t3
    t4
        t2
            t3
t5

有人可以帮忙吗?

提前致谢。

【问题讨论】:

  • t2/t3 目标对发生了什么?
  • 刚刚纠正了我的问题。感谢您发现错误。

标签: python xml bash perl xml-parsing


【解决方案1】:

当我需要将 XML 树操作为其他表示时,我发现先将其转换为抽象表示,然后再转换为最终的具体表示很有用。

在这种情况下,首先我们创建一个表示目标依赖结构的列表字典,然后我们漂亮地打印该字典。

#!/usr/bin/python

import xml.etree.ElementTree as ET
from itertools import chain

def parse(filename):
    tree = ET.parse(filename)
    root = tree.getroot()
    result = {}
    for target in root.findall('target'):
        target_name = target.get('name')
        result[target_name] = []
        for antcall in target.findall('.//antcall'):
            result[target_name].append(antcall.get('target'))
    return result

def display(tree):
    def recurse(node, indent):
        print "%*s%s"%(indent*4, "", node)
        for node in sorted(tree[node]):
            recurse(node, indent+1)
    for item in sorted(tree):
        if item in chain(*tree.values()): continue
        recurse(item,0)

if __name__=="__main__":
    import argparse
    parser = argparse.ArgumentParser(description='Dump ANT files')
    parser.add_argument('antfile',
                        nargs='+',
                        type=argparse.FileType('r'),
                        help='ANT build file')
    args = parser.parse_args()
    for antfile in args.antfile:
        display(parse(antfile))

【讨论】:

  • 谢谢罗伯。该代码有效,但在我的情况下,“antcall”元素可能不是“目标”元素下的下一个元素,它可能是一个或多个级别。也就是说,它们可以出现在文档树的更深处……并且每个“目标”都包含多个“antcall”元素。
  • re: "not imediate next element under",你可以在target.findall()中使用XPath表达式。回复:“多个'antcall'”,您可以将它们存储在字典中的列表中。查看我最近的编辑。
  • 非常感谢罗布。一个完美的。
猜你喜欢
  • 2021-12-29
  • 2014-02-27
  • 1970-01-01
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2020-07-01
相关资源
最近更新 更多