【问题标题】:How to produce xml structure up to certain xml node ussing Python?如何使用 Python 生成直到某个 xml 节点的 xml 结构?
【发布时间】:2016-10-27 05:13:17
【问题描述】:

我对这些东西很陌生。由于我的原始 xml 大约 8GB,因此很难手动探索原始 xml 中感兴趣的孩子的所有父母、祖父母、祖父母等。我正在尝试查看所有节点,直到找到感兴趣的孩子。所以我想从这里https://docs.python.org/2/library/xml.etree.elementtree.html 为 country_data.xml 感兴趣的孩子创建 xml 的“骨架”结构。对不起代码:

def LookThrougStructure(parent, xpath_str, stop_flag):
    out_str.write('Parent tag: %s\n' % (parent.tag))
    for child in parent:
        if child.tag == my_tag:
            out_str.write('Child tag: %s\n' % (child.tag))
            #my_node_is_found_flag = 1
            break
        LookThrougStructure(child, child.tag, 0)
    return  
import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
my_tag = 'neighbor'
out_str = open('xml_structure.txt', 'w')
LookThrougStructure(root, root.tag, my_tag)
out_str.close()

它工作错误并产生所有节点标签:

父标签:data 父标签:country 父标签:rank 父标签:year 父标签:gdppc 子标签:neighbor 父标签:country 父标签: rank 父标签:year 父标签:gdppc 子标签:neighbor Parent 标签:国家 父标签:等级 父标签:年份 父标签:gdppc 子 标签:邻居

但我想要这样的东西(我感兴趣的孩子是“邻居”):

  • 数据
    • 国家
      • 邻居

或者那个:/data/country/neighbor。 怎么了?

【问题讨论】:

  • 您能否以正确的格式添加实际输出,因为我不太明白您想要什么
  • 是:见上文。我不需要排名、年份、gdppc 之类的东西,我只想查看邻居标签的所有父节点。
  • 所以基本上你只希望祖先到邻居?

标签: python xml lxml


【解决方案1】:

如果我理解正确的话,你想要这样的东西:

look_through_structure(parent, my_tag):
    for node in parent.iter("*"):
        out_str.write('Parent tag: %s\n' % node.tag)
        for nxt in node:
            if nxt.tag == my_tag:
                out_str.write('child tag: %s\n' % my_tag)
                return
            out_str.write('Parent tag: %s\n' % nxt.tag)
            if any(ch.tag == my_tag for ch in nxt.getchildren()):
                out_str.write('child tag: %s\n' % my_tag)
                return

如果我们稍微改变一下函数并产生标签:

def look_through_structure(parent, my_tag):
    for node in parent.iter("*"):
        yield node.tag
        for nxt in node:
            if nxt.tag == my_tag:
                yield nxt.tag
                return
            yield nxt.tag
            if any(ch.tag == my_tag for ch in nxt.getchildren()):
                yield my_tag
                return

并在文件上运行它:

In [24]: root = tree.getroot()

In [25]: my_tag = 'neighbor'

In [26]: list(look_through_structure(root, my_tag))
Out[26]: ['data', 'country', 'neighbor']

另外,如果您只想要完整路径,lxml 的 getpath 会为您完成:

import lxml.etree as ET

tree = ET.parse('country.xml')

my_tag = 'neighbor'

print(tree.getpath(tree.find(".//neighbor")))

输出:

/data/country[1]/neighbor[1]

【讨论】:

    【解决方案2】:

    @帕德拉克。非常感谢!您的代码主要是我想要的。但是,如果我插入附加节点(例如属性),它是国家节点的子节点和邻居节点的父节点,它会给出意想不到的结果:

    <data>
    <country name="Liechtenstein">
    <attributes>
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
        </attributes>
    </country>
    <country name="Singapore">
    <attributes>
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
        </attributes>
    </country>
    <country name="Panama">
    <attributes>
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
        </attributes>
    </country>
    

    不管怎样,你的帮助很有成效。我拿了你的代码并创建了这个:

    import lxml.etree as et
    root = et.parse('country_data.xml')
    
    out_f = open('getpath.txt', 'w')
    
    my_str1 = 'country[1]'
    my_str2 = 'neighbor[1]'
    
    for e in root.iter():
        s = root.getelementpath(e)
        if my_str1 not in s:
            continue
        if my_str2 not in s:
            continue
        out_f.write('%s\n' %(s))
        break
    out_f.close()
    

    这个想法很简单:如果 elementpath 有字符串 'country' 和 'neighbor' ,它会被写入输出文件。对于原始 xml 示例,它给出:country[1]/neighbor[1]。对于带有附加父级的 xml,它给出:country[1]/attributes/neighbor[1]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多