python,xml:如何通过元素名称访问第三个孩子

Posted

技术标签:

【中文标题】python,xml:如何通过元素名称访问第三个孩子【英文标题】:python, xml: how to access the 3rd child by element' name 【发布时间】:2021-01-28 23:18:07 【问题描述】:

请您帮我通过以下 Python 结构访问名为“id”的元素(我有 lxml 和 xml.etree.ElementTree 库)。

理想的结果:'0000000' 理想的方法:

    在 xml 文档中搜索一个名为 fcsProtocolEF3 的孩子。 在 fcsProtocolEF3 中搜索名为“id”的元素。

按元素名称搜索至关重要。不是按序号。

我尝试使用这样的东西:tree.findall('http://zakupki.gov.ru/oos/export/1fcsProtocolEF3')[0].findall('http://zakupki.gov.ru/oos/types/1id')[0].text

它可以工作,但它需要输入命名空间。 XML 文档有不同的命名空间,我不知道如何事先定义它们。

谢谢。

在 SQL 中使用 XQuery 之类的东西会很棒:

value('(/*:export/*:fcsProtocolEF3/*:id)[1]', 'nvarchar(21)')) AS [id],

XML 文档:

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
 <ns2:export xmlns:ns3="http://zakupki.gov.ru/oos/common/1" xmlns:ns4="http://zakupki.gov.ru/oos/base/1" xmlns:ns2="http://zakupki.gov.ru/oos/export/1" xmlns:ns10="http://zakupki.gov.ru/oos/printform/1" xmlns:ns11="http://zakupki.gov.ru/oos/control99/1" xmlns:ns9="http://zakupki.gov.ru/oos/SMTypes/1" xmlns:ns7="http://zakupki.gov.ru/oos/pprf615types/1" xmlns:ns8="http://zakupki.gov.ru/oos/EPtypes/1" xmlns:ns5="http://zakupki.gov.ru/oos/TPtypes/1" xmlns:ns6="http://zakupki.gov.ru/oos/CPtypes/1" xmlns="http://zakupki.gov.ru/oos/types/1">
   <ns2:fcsProtocolEF3 schemeVersion="10.2">
     <id>0000000</id>
     <purchaseNumber>0000000000000000</purchaseNumber>
   </ns2:fcsProtocolEF3>
 </ns2:export>

【问题讨论】:

请上传一个有效的 xml。当前的无效 balderman,谢谢您的回复。我已经在文档中添加了结尾。 您当前的解决方案有什么问题?由于 XML 文档基于 NS - 您必须使用它们。不是吗?您希望拥有什么? 【参考方案1】:

lxml解决方案:

xml = '''<?xml version="1.0"?>
 <ns2:export xmlns:ns3="http://zakupki.gov.ru/oos/common/1" xmlns:ns4="http://zakupki.gov.ru/oos/base/1" xmlns:ns2="http://zakupki.gov.ru/oos/export/1" xmlns:ns10="http://zakupki.gov.ru/oos/printform/1" xmlns:ns11="http://zakupki.gov.ru/oos/control99/1" xmlns:ns9="http://zakupki.gov.ru/oos/SMTypes/1" xmlns:ns7="http://zakupki.gov.ru/oos/pprf615types/1" xmlns:ns8="http://zakupki.gov.ru/oos/EPtypes/1" xmlns:ns5="http://zakupki.gov.ru/oos/TPtypes/1" xmlns:ns6="http://zakupki.gov.ru/oos/CPtypes/1" xmlns="http://zakupki.gov.ru/oos/types/1">
   <ns2:fcsProtocolEF3 schemeVersion="10.2">
     <id>0000000</id>
     <purchaseNumber>0000000000000000</purchaseNumber>
   </ns2:fcsProtocolEF3>
 </ns2:export>'''
 
from lxml import etree as et

root = et.fromstring(xml)
text = root.xpath('//*[local-name()="export"]/*[local-name()="fcsProtocolEF3"]/*[local-name()="id"]/text()')[0]
print(text)

【讨论】:

亚历山德拉,非常感谢。这正是我所需要的。文件中的 NS 可能因文件而异。唯一不变的就是路径:extport/fcsProtocolEF3/id。因此我需要一个不明确使用 NS 的解决方案。【参考方案2】:

以下是基于 ET 的解决方案。 NS 正在使用中。

import xml.etree.ElementTree as ET

xml = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ns2:export xmlns:ns3="http://zakupki.gov.ru/oos/common/1" xmlns:ns4="http://zakupki.gov.ru/oos/base/1" xmlns:ns2="http://zakupki.gov.ru/oos/export/1" xmlns:ns10="http://zakupki.gov.ru/oos/printform/1" xmlns:ns11="http://zakupki.gov.ru/oos/control99/1" xmlns:ns9="http://zakupki.gov.ru/oos/SMTypes/1" xmlns:ns7="http://zakupki.gov.ru/oos/pprf615types/1" xmlns:ns8="http://zakupki.gov.ru/oos/EPtypes/1" xmlns:ns5="http://zakupki.gov.ru/oos/TPtypes/1" xmlns:ns6="http://zakupki.gov.ru/oos/CPtypes/1" xmlns="http://zakupki.gov.ru/oos/types/1">
   <ns2:fcsProtocolEF3 schemeVersion="10.2">
     <id>0000000</id>
     <purchaseNumber>0000000000000000</purchaseNumber>
   </ns2:fcsProtocolEF3>
 </ns2:export>

'''

def get_id_text():
  root = ET.fromstring(xml)
  fcs = root.find('http://zakupki.gov.ru/oos/export/1fcsProtocolEF3')
  # assuming there is one fcs element and one id under fcs
  return fcs.find('http://zakupki.gov.ru/oos/types/1id').text
print(get_id_text())

输出

0000000

【讨论】:

以上是关于python,xml:如何通过元素名称访问第三个孩子的主要内容,如果未能解决你的问题,请参考以下文章

如何通过名称和数组访问成员?

python中常见的报错,总结一下,以后看。

python第四天高级特性

如何使用python修改xml文件中嵌套元素的文本?

Python--列表

如何访问名称无效的属性?