Python:XML列表索引超出范围

问题描述:

我有麻烦去获取一些XML文件中的值。 错误是IndexError: list index out of rangePython: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格式的,那些vICMSvICMSST标签:

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' 

您在代码中犯了几个常见错误。

  1. 不要使用计数器索引到您不知道长度的列表中。通常,使用for .. in进行迭代比使用索引好很多。
  2. 你有许多进口,你似乎没有使用,摆脱他们。
  3. 您可以使用minidom,但ElementTree更适合您的任务,因为它支持使用XPath搜索节点,并且它支持XML名称空间。
  4. 请勿将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' 
+0

感谢您的回复。很高兴知道我可以改进代码。他的方法好得多,我会研究它。 – user2925795

只有一个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