python,如何查找父元素

时间:2015-01-13 14:31:57

标签: python lxml

我有内容

的XML文件
<work>
  <person>
    <name>Jim</name>
    <id>100</id>
    <supervisor></supervisor>
  </person>
  <person>
    <name>Jack</name>
    <id>101</id>
    <supervisor>100</supervisor>
  </person>
  <person>
    <name>Joe</name>
    <id>102</id>
    <supervisor>101</supervisor>
  </person>
  <person>
    <name>John</name>
    <id>103</id>
    <supervisor>102</supervisor>
  </person>
</work>

我想让所有人都知道谁是最高老板。 例如乔,他的直接主管是杰克,但我想找出层次结构的顶部,即吉姆。

所以,像

for person in persons
  top_boss=find_top_boss(supervisor)
  print name,top_boss

find_top_boss(主管)需要在层次结构中上升,直到找到Jim,可能需要递归调用自己。

我需要返回列表(姓名,顶级老板):

  • 吉姆,空
  • 杰克,吉姆
  • 乔,吉姆
  • 约翰,吉姆

我使用python和提供工具的任何模块,现在尝试使用LXML。

我现在处于开始状态,而且我能够遍历这些人,但不知道如何搜索主管? 我对python,lxml或xpath的了解非常有限。

from lxml import etree
tree = etree.parse("work.xml")
for person in tree.xpath('//person'):
  # search supervisor for the person
  s = person.xpath("//id[text()=supervisor-element-value]")[0]
  print s.text    

所以,问题:

  1. 如何使用当前人物项目中的监督元素值 xpath搜索?
  2. 如果我能找到主管,请说我会使用静态值 在xpath中

    s = person.xpath(&#34; // id [text()=&#39; 101&#39;]&#34;)[0]

  3. 我会找到杰克。我怎样才能获得Jacks监督元素的Jacks价值 我是否需要先找到Jacks父元素或如何?

1 个答案:

答案 0 :(得分:1)

我使用xmltodict包将XML转储到python数据结构中然后使用它。

工作示例(在算法方面并不完美,但应该给你一个起点):

from collections import OrderedDict
import xmltodict

data = """
<work>
  <person>
    <name>Jim</name>
    <id>100</id>
    <supervisor></supervisor>
  </person>
  <person>
    <name>Jack</name>
    <id>101</id>
    <supervisor>100</supervisor>
  </person>
  <person>
    <name>Joe</name>
    <id>102</id>
    <supervisor>101</supervisor>
  </person>
  <person>
    <name>John</name>
    <id>103</id>
    <supervisor>102</supervisor>
  </person>
</work>
"""

d = xmltodict.parse(data)

persons = OrderedDict((person['id'], person) for person in d['work']['person'])

def get_supervisor(person):
    if not person['supervisor']:
        return 'null'
    else:
        supervisor = persons[person['supervisor']]
        if not supervisor['supervisor']:
            return supervisor['name']
        else:
            return get_supervisor(supervisor)

for person in persons.itervalues():
    print person['name'], get_supervisor(person)

打印:

Jim null
Jack Jim
Joe Jim
John Jim