繁体   English   中英

当您知道带有xpath的子文本时,python lxml获取父元素

[英]python lxml get parent element when you know child text with xpath

我有以下xml文件: test.xml

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <SubmitTransaction xmlns="http://www.someaddress.com/someendpoint">
      <objTransaction>
        <DataFields>
          <TxnField>
            <FieldName>Pickup.Address.CountryCode</FieldName>
            <FieldValue>DE</FieldValue>
            <FieldIndex>0</FieldIndex>
          </TxnField>
          <TxnField>
            <FieldName>Pickup.Address.PostalCode</FieldName>
            <FieldValue>10827</FieldValue>
            <FieldIndex>0</FieldIndex>
          </TxnField>
          <TxnField>
            <FieldName>Pickup.DateTime</FieldName>
            <FieldValue>2016-05-28T03:26:05</FieldValue>
            <FieldIndex>0</FieldIndex>
          </TxnField>
          <TxnField>
            <FieldName>Pickup.LocationTypeCode</FieldName>
            <FieldValue>O</FieldValue>
            <FieldIndex>0</FieldIndex>
          </TxnField>
          <TxnField>
            <FieldName>Pickup.Address.City</FieldName>
            <FieldValue>Berlin</FieldValue>
            <FieldIndex>0</FieldIndex>
          </TxnField>
        </DataFields>
      </objTransaction>
    </SubmitTransaction>
  </soap:Body>
</soap:Envelope>

我想做的是获取一个带有标签TxnField的元素,该元素具有带有文本Pickup.DateTime的子FieldName 获取父元素很重要,因此我需要获取此元素:

<TxnField>
  <FieldName>Pickup.DateTime</FieldName>
  <FieldValue>2016-05-28T03:26:05</FieldValue>
  <FieldIndex>0</FieldIndex>
</TxnField>

我到目前为止有以下内容:

from lxml import etree
xml_parser = etree.XMLParser(remove_blank_text=True)
xml_tree = etree.parse('test.xml', xml_parser)

p_time = xml_tree.xpath("//*[local-name()='TxnField']/*[text()='Pickup.DateTime']")
print(p_time[0].tag) # {http://http://www.someaddress.com/someendpoint}FieldName

但这给了我带有文本Pickup.DateTime的实际元素,并且我对获取其父元素感兴趣,如上所示。

附带说明 :到目前为止,我花了将近一个小时的时间,因为我发现lxml文档非常繁琐。 如果有人链接了一个很好的教程,请至少将其发布为评论。 谢谢!

我已经找到了如何获得它:

p_time = xml_tree.xpath("//*[local-name()='TxnField']/*[text()='Pickup.DateTime']/./..")

这是一个建议:

from lxml import etree

NSMAP = {"s": "http://www.someaddress.com/someendpoint"}

xml_parser = etree.XMLParser(remove_blank_text=True)
xml_tree = etree.parse('test.xml', xml_parser)

p_time = xml_tree.xpath("//s:FieldName[.='Pickup.DateTime']", namespaces=NSMAP)[0]
parent = p_time.getparent()
  • 声明s前缀绑定到http://www.someaddress.com/someendpoint命名空间。 它用于XPath表达式中,而不是local-name()
  • xpath()的调用返回一个包含一个项目(所需的FieldName元素)的列表,然后使用getparent()方法查找其父项。

有多种方法可以做到!

顺便说一句,我认为这是一个非常不错的lxml教程: http : //infohost.nmt.edu/tcc/help/pubs/pylxml/web/index.html

首选XPath表达式恕我直言,以使父节点的子节点具有特定值是这样的:

//d:TxnField[d:FieldName='Pickup.DateTime']

以上假设您已将前缀d映射到默认名称空间uri。 但是从您的评论看来,您似乎更喜欢在这里忽略名称空间,因此这是等效的表达式,而不必注册名称空间前缀:

//*[local-name()='TxnField'][*[local-name()='FieldName' and .='Pickup.DateTime']]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM