Python:XML列表索引超出范围
问题描述:
我有麻烦去获取一些XML文件中的值。 错误是IndexError: list index out of range
Python:XML列表索引超出范围
XML
<?xml version="1.0" encoding="UTF-8"?>
<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="3.10">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe Id="NFe35151150306471000109550010004791831003689145" versao="3.10">
<ide>
<nNF>479183</nNF>
</ide>
<emit>
<CNPJ>3213213212323</CNPJ>
</emit>
<det nItem="1">
<prod>
<cProd>7030-314</cProd>
</prod>
<imposto>
<ICMS>
<ICMS10>
<orig>1</orig>
<CST>10</CST>
<vICMS>10.35</vICMS>
<vICMSST>88.79</vICMSST>
</ICMS10>
</ICMS>
</imposto>
</det>
<det nItem="2">
<prod>
<cProd>7050-6</cProd>
</prod>
<imposto>
<ICMS>
<ICMS00>
<orig>1</orig>
<CST>00</CST>
<vICMS>7.49</vICMS>
</ICMS00>
</ICMS>
</imposto>
</det>
</infNFe>
</NFe>
</nfeProc>
我越来越从XML值,这是确定以XML格式的,那些vICMS和vICMSST标签:
vicms = doc.getElementsByTagName('vICMS')[i] .firstChild.nodeValue
vicmsst = doc.getElementsByTagName( 'vICMSST')[1] .firstChild.nodeValue
这将返回:
首先返回:
print vicms
>> 10.35
print vicmsst
>> 88.79
二imposto崩溃,因为不要't找到vICMSST标记...
**IndexError: list index out of range**
测试它的最佳形式是什么?我使用xml.etree.ElementTree:
我的代码:
import os
import sys
import subprocess
import base64,xml.dom.minidom
from xml.dom.minidom import Node
import glob
import xml.etree.ElementTree as ET
origem = 0
# only loops over XML documents in folder
for file in glob.glob("*.xml"):
f = open("%s" % file,'r')
data = f.read()
i = 0
doc = xml.dom.minidom.parseString(data)
for topic in doc.getElementsByTagName('emit'):
#Get Fiscal Number
nnf= doc.getElementsByTagName('nNF')[i].firstChild.nodeValue
print 'Fiscal Number %s' % nnf
print '\n'
for prod in doc.getElementsByTagName('det'):
vicms = 0
vicmsst = 0
#Get value of ICMS
vicms = doc.getElementsByTagName('vICMS')[i].firstChild.nodeValue
#Get value of VICMSST
vicmsst = doc.getElementsByTagName('vICMSST')[i].firstChild.nodeValue
#PRINT INFO
print 'ICMS %s' % vicms
print 'Valor do ICMSST: %s' % vicmsst
print '\n\n'
i +=1
print '\n\n'
答
您在代码中犯了几个常见错误。
- 不要使用计数器索引到您不知道长度的列表中。通常,使用
for .. in
进行迭代比使用索引好很多。 - 你有许多进口,你似乎没有使用,摆脱他们。
- 您可以使用
minidom
,但ElementTree
更适合您的任务,因为它支持使用XPath搜索节点,并且它支持XML名称空间。 - 请勿将XML文件读取为字符串,然后使用
parseString
。让XML解析器直接处理文件。这样所有文件编码相关的问题将被处理而不会出错。
以下是比你原来的方法好很多。
import glob
import xml.etree.ElementTree as ET
def get_text(context_elem, xpath, xmlns=None):
""" helper function that gets the text value of a node """
node = context_elem.find(xpath, xmlns)
if (node != None):
return node.text
else:
return ""
# set up XML namespace URIs
xmlns = {
"nfe": "http://www.portalfiscal.inf.br/nfe"
}
for path in glob.glob("*.xml"):
doc = ET.parse(path)
for infNFe in doc.iterfind('.//nfe:infNFe', xmlns):
print 'Fiscal Number\t%s' % get_text(infNFe, ".//nfe:nNF", xmlns)
for det in infNFe.iterfind(".//nfe:det", xmlns):
print ' ICMS\t%s' % get_text(det, ".//nfe:vICMS", xmlns)
print ' Valor do ICMSST:\t%s' % get_text(det, ".//nfe:vICMSST", xmlns)
print '\n\n'
答
只有一个vICMSST
在XML文档中的标签。所以,当i=1
时,以下行返回IndexError
。
vicmsst = doc.getElementsByTagName('vICMSST')[1].firstChild.nodeValue
可以重组这:
try:
vicmsst = doc.getElementsByTagName('vICMSST')[i].firstChild.nodeValue
except IndexError:
# set a default value or deal with this how you like
这很难说,你应该在一个异常做什么不知道更多关于你想要做什么。
+0
谢谢,@o_o!我从Python开始,感谢您的解释。 – user2925795
感谢您的回复。很高兴知道我可以改进代码。他的方法好得多,我会研究它。 – user2925795