2017-08-03 108 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