2017-08-03 97 views
0

这里我需要解析xml并获取值。我需要获取像'personid = 01'这样的属性元素,这是我无法获得的代码。而且我还需要获取大的孩子节点值。这里是“SIBLING”及其名称标签。但我无法将其作为兄弟代码硬编码并获取其值。最重要的是,我需要处理多个属性并将它们连接起来形成一个唯一的键,这个键将作为决赛桌中的一列。xml到python的csv转换

import xml.dom 
import xml.dom.minidom 

doc = xml.dom.minidom.parseString(''' 
<root> 
    <person id="01"> 
     <name> abc</name> 
     <age>32</age> 
     <address>addr123</address> 
     <siblings> 
     <name></name> 
     </siblings> 
    </person> 
    <person id="02"> 
     <name> def</name> 
     <age>22</age> 
     <address>addr456</address> 
     <siblings> 
     <name></name> 
     <name></name> 
     </siblings> 
    </person> 
</root> 

''') 

innerlist=[] 
outerlist=[] 
def innerHtml(root): 
    text = '' 
    nodes = [ root ] 
    while not nodes==[]: 
     node = nodes.pop() 
     if node.nodeType==xml.dom.Node.TEXT_NODE: 
      text += node.wholeText 
     else: 
      nodes.extend(node.childNodes) 
    return text 

for statusNode in doc.getElementsByTagName('person'): 
    for childNode in statusNode.childNodes: 
     if childNode.nodeType==xml.dom.Node.ELEMENT_NODE: 
      if innerHtml(childNode).strip() != '': 
       innerlist.append(childNode.nodeName+" "+innerHtml(childNode).strip()) 
    outerlist.append(innerlist) 
    innerlist=[] 
#print(outerlist) 

attrlist = [] 
nodes = doc.getElementsByTagName('person') 
for node in nodes: 
    if 'id' in node.attributes: 
     #print(node.attributes['id'].value) 
     attrlist.append(node.attributes['id'].value) 
#print(attrlist) 

dictionary = dict(zip(attrlist, outerlist)) 
print(dictionary) 

回答

0

评论:我已经将其存储在一个dictnorary。 {'01': ['name abc', 'age 32', 'address addr123'], '02': ['name def', 'age 22', 'address addr456']}

你不能写一个dict到CSV!

ValueError: dict contains fields not in fieldnames: '01' 

REALY要转换为CSV
阅读CSV File Reading and Writing

评论:在这里,我需要得到也sibiling标签作为另一个innerlist。

CSV不到风度支持这种innerlist
编辑您的问题并显示预期的CSV输出!


问题:XML到CSV转换

解决方案与xml.etree.ElementTree

注意:不明白你希望如何处理孙子节点值
将其作为列表dict写入一列中。

import csv 
import xml.etree.ElementTree as ET 
root = ET.fromstring(doc) 

fieldnames = None 
with open('doc.csv', 'w') as fh: 
    for p in root.findall('person'): 
     person = {'_id':p.attrib['id']} 
     for element in p: 
      if len(element) >= 1: 
       person[element.tag] = [] 
       for sub_e in element: 
        person[element.tag].append({sub_e.tag:sub_e.text}) 
      else: 
       person[element.tag] = element.text 

     if not fieldnames: 
      fieldnames = sorted(person) 
      w = csv.DictWriter(fh, fieldnames=fieldnames) 
      w.writeheader() 

     w.writerow(person) 

输出

_id,address,age,name,siblings 
01,addr123,32, abc,[{'name': 'sib1'}] 
02,addr456,, def,"[{'name': 'sib2'}, {'name': 'sib3'}]" 

测试使用Python 3.4.2

+0

我喜欢输出下面。我在上面的代码中做了一些改动。 personid被用作唯一的关键字来标识其价值。我已经将它存储在一个字典中。 {'01':['name abc','age 32','address addr123'],'02':['name def','age 22','address addr456']}。在这里,我需要将sibiling标签作为另一个内部列表。 – nishanth

+0

在上面的代码中,我已经跳过了给“兄弟”名称属性的值。如果“兄弟名称”标签为空,我的代码将不会追加它。但是,如果兄弟标签具有值,则它必须附加为内部列表。在唯一的关键字“personid”下。我已经使用.strip()来避免空的空间.Constrain是如果值在那里它应该显示。如果值不存在,那么它不应该显示。对我来说,它没有显示,因为价值观不存在。但是如果值存在,它应该显示。 – nishanth

+0

请尝试更正我的代码itslf而不更改完整的代码。如果可能的话。谢谢。 – nishanth