我是Python和XML的新手,并尝试解析下面的文件以提取多个元素。问题是某些元素是空的(例如客户xyz1没有任何地址信息)。
<script type="text/javascript">
$( document ).ready(function() {
$('#twit-follow-count').html('<?php echo $followers_count; ?>');
});
</script>
我循环遍历以下元素(Id_Customer,Segment,Extrainfo,zipcode,street)以构建一个列表,然后我将导出到.csv文件。
我的代码生成以下输出:[xyz1,abc1,info2,zzwy,c2 ..]虽然我希望找不到的元素在列表中输入为“空”,以便我的列表包含:[xyz1 ,abc1,info2,空,空,zzwy,c2 ..]
以下是我的代码示例:
<CAT>
<Header>...</Header>
<Add>...</Add>
<Customer>
<Id_Customer>xyz1</Id_Customer>
<Segment>abc1</Segment>
<Event>
<Nature>info1</Nature>
<Extrainfo>info2</Extrainfo>
</Event>
</Customer>
<Customer>
<Id_Customer>zzwy</Id_Customer>
<Segment>c2</Segment>
<Adress>
<zipcode>77098</zipcode>
<street>belaire drive</street>
<number>5</number>
</Adress>
</Customer>
<Customer>...</Customer>
</CAT>
我非常感谢一些帮助。 (我只能使用标准的python库。)
答案 0 :(得分:0)
查看xml.etree(https://docs.python.org/3.6/library/xml.etree.elementtree.html)的方法 findtext ,默认值。
我想以下内容可能有效(未经测试),每个客户都在一个单独的列表中(如csv文件中的行),然后插入到一般的list_prn列表中。当然,在构建csv文件时,您必须遍历列表。
如果您真的想要一个列表中的所有元素值,您可以跳过创建cust列表并将值直接插入list_prn。
这一切都表明客户的所有子元素都只存在一次。
from xml.etree import ElementTree
import csv
list_prm = []
tree = ElementTree.parse('file.xml')
root = tree.getroot()
for elem in tree.iter('Customer'):
# only the first customer_id
customer_id = elem.find('Id_Customer')
if customer_id is not None:
# Create a separate list for each Customer,
# only if there's Customer Id, skip creation otherwise
cust = []
cust.append(customer_id.text())
cust.append(elem.findtext('Segment', default='empty'))
cust.append(elem.findtext('Extrainfo', default='empty'))
cust.append(elem.findtext('Address/street', default='empty'))
cust.append(elem.findtext('Address/zipcode', default='empty'))
list_prm.append(cust)
print(list_prm)
答案 1 :(得分:0)
您的主要问题是,您实际上只是将数据从XML中提取到CSV中,而其状态与您发现的几乎相同。您所指的“空”元素不为空,它们不存在于XML中。
我可以考虑使用两种方法来改善这项工作。第一种方法是更改XML,使每个<Customer>
元素包含相同顺序的所有元素,即使元素完全为空。换句话说,您的XML可能如下所示:
<Customer>
<Id_Customer>xyz1</Id_Customer>
<Segment>abc1</Segment>
<Event>
<Nature>info1</Nature>
<Extrainfo>info2</Extrainfo>
</Event>
<Adress>
<zipcode></zipcode>
<street></street>
<number></number>
</Adress>
</Customer>
<Customer>
<Id_Customer>zzwy</Id_Customer>
<Segment>c2</Segment>
<Event>
<Nature></Nature>
<Extrainfo></Extrainfo>
</Event>
<Adress>
<zipcode>77098</zipcode>
<street>belaire drive</street>
<number>5</number>
</Adress>
</Customer>
如果你想要,你可以在你的Python代码中添加一个条件,将空字符串(""
)替换为单词“empty”,因为你表明这是你想说的。
另一种方法会产生更复杂的Python代码,但老实说可能是更好的方法。那就是使用类或字典对数据进行排序:每个<Customer>
标记一个字典或对象。你正在做什么我会说创建一个类可能有点矫枉过正,所以dict就足够了。 (使用defaultdict而不是普通的dict可以让你在没有找到值时自动提供“empty”这个词,所以我会调查一下。)
基本上程序的流程如下:
customers = []
<Customer>
元素。对于每个客户:
customer={}
或customer=defaultdict("empty")
,然后是customers.append(customer)
customer[elem.tag]=elem.text
这样的东西可能就是你要找的东西。keys=["Id_Customer", "Segment", etc...]
for customer in customers:
对于每次迭代:
for key in keys:
csv.write(customer[key])
(当然你也要在这一点上把逗号写入文件,除非它是最后一次迭代keys
循环,然后编写换行符。您可以使用key == keys[-1]
)