2017-02-09 32 views
1

我想通過編寫一個腳本來從Python中的多個記錄中提取數據來學習Python。我已經能夠通過在網上搜索找到我的大多數問題的答案,但是我還沒有找到一種方法來確定XML標記在getElementsByTagName之前是否不包含數據(「標記名」)[0] .firstChild .data方法被使用,並且當沒有數據存在時拋出一個AttributeError。我意識到我可以通過嘗試編寫我的代碼並處理AttributeError,但我寧願知道在我嘗試提取數據而不必處理異常之前該標記爲空。 下面是一個XML文件的示例,其中包含兩個記錄,一個包含標記中的數據,另一個包含空標記。使用Python 3.6解析XML如何確定XML標記是否不包含數據

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?> 
<records> 
    <rec> 
    <name>ZYSRQPO</name> 
    <state>Washington</state> 
    <country>United States</country> 
    </rec> 
    <rec> 
    <name>ZYXWVUT</name> 
    <state></state> 
    <country>Mexico</country> 
    </rec> 
</records> 

這裏是我可能會用它來提取數據的代碼示例:

from xml.dom import minidom 
import sys 

mydoc = minidom.parse('mydataFile.xml') 
records = mydoc.getElementsByTagName("rec") 

for rec in records: 
    try: 
     name = rec.getElementsByTagName("name")[0].firstChild.data 
     state = rec.getElementsByTagName("state")[0].firstChild.data 
     country = rec.getElementsByTagName("country")[0].firstChild.data 
     print('{}\t{}\t{}'.format(name, state, country)) 

    except (AttributeError): 
     print('AttributeError encountered in record {}'.format(name), file=sys.stderr) 
     continue 

在處理這個文件將被印刷不同的是,遇到異常沒有信息名爲ZYXWVUT記錄。我希望能夠爲所使用的州名和其他有關此記錄的信息打印出空值。有沒有一種方法可以用來做我想做的事情,以便我可以使用if語句來確定標記在使用getElementsByTagName之前是否不包含數據,並且在沒有找到數據時遇到錯誤?

回答

1
from xml.dom import minidom 
import sys 

mydoc = minidom.parse('mydataFile.xml') 
records = mydoc.getElementsByTagName("rec") 

for rec in records: 
    name = rec.getElementsByTagName("name")[0].firstChild.data 
    state = None if len(rec.getElementsByTagName("state")[0].childNodes) == 0 else rec.getElementsByTagName("state")[0].firstChild.data 
    country = rec.getElementsByTagName("country")[0].firstChild.data 
    print('{}\t{}\t{}'.format(name, state, country)) 

或者,如果有任何機會,這個名字和國家爲空太:

from xml.dom import minidom 
import sys 


def get_node_data(node): 
    if len(node.childNodes) == 0: 
     result = None 
    else: 
     result = node.firstChild.data 
    return result 


mydoc = minidom.parse('mydataFile.xml') 
records = mydoc.getElementsByTagName("rec") 

for rec in records: 
    name = get_node_data(rec.getElementsByTagName("name")[0]) 
    state = get_node_data(rec.getElementsByTagName("state")[0]) 
    country = get_node_data(rec.getElementsByTagName("country")[0]) 
    print('{}\t{}\t{}'.format(name, state, country)) 
+0

謝謝你,我很欣賞你的反應。我特別喜歡第二個建議,儘管任何名字或國家都不會有空的機會,因此可以找到更優雅的結構。我有其他地方,我需要現在,所以我沒有嘗試過,但會盡快嘗試。 – JCB

0

我試圖reedcourty的第二項建議,並發現它真是棒極了。但我決定,如果元素爲空,我真的不希望沒有人返回。以下是我想出了:

from xml.dom import minidom 
import sys 

def get_node_data(node): 
    if len(node.childNodes) == 0: 
     result = '*->No ' + node.nodeName + '<-*' 
    else: 
     result = node.firstChild.data 
    return result 

mydoc = minidom.parse(dataFileSpec) 
records = mydoc.getElementsByTagName("rec") 

for rec in records: 
    name = get_node_data(rec.getElementsByTagName("name")[0]) 
    state = get_node_data(rec.getElementsByTagName("state")[0]) 
    country = get_node_data(rec.getElementsByTagName("country")[0]) 
    print('{}\t{}\t{}'.format(name, state, country)) 

當這對這個XML運行:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?> 
<records> 
    <rec> 
    <name>ZYSRQPO</name> 
    <country>United States</country> 
    <state>Washington</state> 
    </rec> 
    <rec> 
    <name></name> 
    <country>United States</country> 
    <state>Washington</state> 
    </rec> 
    <rec> 
    <name>ZYXWVUT</name> 
    <country>Mexico</country> 
    <state></state> 
    </rec> 
    <rec> 
    <name>ZYNMLKJ</name> 
    <country></country> 
    <state>Washington</state> 
    </rec> 
</records> 

它產生這樣的輸出:

ZYSRQPO Washington  United States 
*->No name<-* Washington  United States 
ZYXWVUT *->No state<-* Mexico 
ZYNMLKJ Washington  *->No country<-*