lxml通过使用find表达式中的变量在xml中按text属性查找元素

时间:2017-02-02 19:50:38

标签: python python-2.7 lxml

我在使用find解析XML对象时遇到问题。

我从http响应中读取了我的XML对象,响应是我从http例程中得到的html主体:

xml_obj = objectify.XML(response)

这是我的XML对象:

print etree.tostring(xml_obj, pretty_print=True)

<kids>
  <kid>
    <id>110</id>
    <name>Peter</name> 
  </kid>
  <kid>
    <id>111</id>
    <name>Paul</name>
  </kid>
  <kid>
    <id>112</id>
    <name>Mary</name>
  </kid>
  <kid>
    <id>113</id> 
    <name>Jane</name>
  </kid>
</kids>

这是我按名称搜索小孩的代码:

kid_obj = xml_obj.find(‘.//kid/name[text()=“Jane”]’).getparent()
print etree.tostring(kid_obj, pretty_print=True)

<kid>
  <id>113</id> 
  <name>Jane</name>
</kid>

只要用变量替换字符串,它就不起作用:

kidname = “Jane”
kid_obj = xml_obj.find(‘.//kid/name[text()=kidname]').getparent()
print etree.tostring(kid_obj, pretty_print=True)

AttributeError: 'NoneType' object has no attribute 'getparent'

这也不起作用:

kidname = “Jane”
kid_obj = xml_obj.find('.//step/name[text()={0}]’.format(kidname)).getparent()
print etree.tostring(kid_obj, pretty_print=True)

AttributeError: 'NoneType' object has no attribute 'getparent'

在我睡了一晚之后,我终于找到了一个有效的解决方案,但也许不是最优雅的代码:

kidname = 'Jane'
kid_obj = xml_obj.find('.//kid/name[text()="'+kidname+'"]').getparent()
print etree.tostring(kid_obj, pretty_print=True)

<kid>
  <id>113</id> 
  <name>Jane</name>
</kid>

2 个答案:

答案 0 :(得分:0)

在第一个

xml_obj.find(‘.//kid/name[text()=kidname]’)

&#34; kidname&#34;被视为价值而不是变量。一个快速测试是重命名一个名为&#34; kidname&#34;的孩子。

在第二个

xml_obj.find('.//step/name[text()={0}]’.format(kidname))

您没有使用相同的引号(&#39;然后是')。

你可以尝试一下:

xml_obj.find('.//step/name[text()={0}]'.format(kidname))

答案 1 :(得分:0)

第一个例子:

kidname = 'Jane'
kid_obj = xml_obj.find('.//kid/name[text()="{}"]'.format(kidname)).getparent()
print etree.tostring(kid_obj, pretty_print=True)

第二个例子:

kidname = 'Jane'
kids = xml_obj.find('.//kid')
success = False
for kid in kids:
    for property in kid: 
       if property.tag == 'name' and property.text == kidname:
           success = True
    if success:
       break
print etree.tostring(kid, pretty_print=True)

请注意,在两个示例中都没有处理没有找到带有kidname的kid的可能错误。