繁体   English   中英

使用python在xml中查找元素

[英]Finding element in xml with python

我试图解析XML,然后再将其内容转换为列表,然后转换为CSV。 不幸的是,我认为用于查找初始元素的搜索词失败了,从而导致后续搜索在层次结构中进一步进行。 我是XML的新手,所以我尝试了各种名称空间字典的变化,包括名称空间引用...简化的XML如下所示:

 <?xml version="1.0" encoding="utf-8"?> <StationList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:add="http://www.govtalk.gov.uk/people/AddressAndPersonalDetails" xmlns:com="http://nationalrail.co.uk/xml/common" xsi:schemaLocation="http://internal.nationalrail.co.uk/xml/XsdSchemas/External/Version4.0/nre-station-v4-0.xsd" xmlns="http://nationalrail.co.uk/xml/station"> <Station xsi:schemaLocation="http://internal.nationalrail.co.uk/xml/XsdSchemas/External/Version4.0/nre-station-v4-0.xsd"> <ChangeHistory> <com:ChangedBy>spascos</com:ChangedBy> <com:LastChangedDate>2018-11-07T00:00:00.000Z</com:LastChangedDate> </ChangeHistory> <Name>Aber</Name> </Station>​ 

我用来尝试提取com / ... xml / station / ChangedBy元素的代码如下

tree = ET.parse(rootfilepath + "NRE_Station_Dataset_2019_raw.xml")
root = tree.getroot()

#get at the tags and their data
#for elem in tree.iter():
#    print(f"this the tag {elem.tag} and this is the data: {elem.text}")

#open file for writing
station_data = open(rootfilepath + 'station_data.csv','w')

csvwriter = csv.writer(station_data)

station_head = []

count = 0
#inspiration for this code: http://blog.appliedinformaticsinc.com/how-to-  parse-and-convert-xml-to-csv-using-python/
#this is where it goes wrong; some combination of the namespace and the tag can't find anything in line 27, 'StationList'
for member in root.findall('{http://nationalrail.co.uk/xml/station}Station'):
station = []
if count == 0:
changedby = member.find('{http://nationalrail.co.uk/xml/common}ChangedBy').tag
station_head.append(changedby)

    name = member.find('{http://nationalrail.co.uk/xml/station}Name').tag
    station_head.append(name)

    count = count+1

changedby = member.find('{http://nationalrail.co.uk/xml/common}ChangedBy').text
station.append(changedby)

name = member.find('{http://nationalrail.co.uk/xml/station}Name').text
station.append(name)

csvwriter.writerow(station)

我努力了:

  • 使用名称空间的字典,但结果却一无所获
  • 使用硬编码的名称空间,但会导致“属性错误:'NoneType'对象没有属性'tag'

在此先感谢您提供的所有协助。

试试lxml

#!/usr/bin/env python3

from lxml import etree

ns = {"com": "http://nationalrail.co.uk/xml/common"}

with open("so.xml") as f:
    tree = etree.parse(f)
    for t in tree.xpath("//com:ChangedBy/text()", namespaces=ns):
        print(t)

输出:

spascos

您可以使用Beautifulsoup,它是一个html和xml解析器

from bs4 import BeautifulSoup

fd = open(rootfilepath + "NRE_Station_Dataset_2019_raw.xml")  
soup = BeautifulSoup(fd,'lxml-xml')

for i in soup.findAll('ChangeHistory'):      
    print(i.ChangedBy.text)

首先,您的XML无效(文件末尾没有</StationList> )。

假设您具有有效的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<StationList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:add="http://www.govtalk.gov.uk/people/AddressAndPersonalDetails"
            xmlns:com="http://nationalrail.co.uk/xml/common"            xsi:schemaLocation="http://internal.nationalrail.co.uk/xml/XsdSchemas/External/Version4.0/nre-station-v4-0.xsd"
            xmlns="http://nationalrail.co.uk/xml/station">
  <Station xsi:schemaLocation="http://internal.nationalrail.co.uk/xml/XsdSchemas/External/Version4.0/nre-station-v4-0.xsd">
    <ChangeHistory>
      <com:ChangedBy>spascos</com:ChangedBy>
      <com:LastChangedDate>2018-11-07T00:00:00.000Z</com:LastChangedDate>
    </ChangeHistory>
    <Name>Aber</Name>
  </Station>​
</StationList>

然后,您可以将XML转换为JSON并简单地寻址为所需的值:

import xmltodict
with open('file.xml', 'r') as f:
    data = xmltodict.parse(f.read())
changed_by = data['StationList']['Station']['ChangeHistory']['com:ChangedBy']

输出:

spascos

暂无
暂无

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

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