lxml XMLSyntaxError: 未找到命名空间默认前缀

0 投票
2 回答
2959 浏览
提问于 2025-04-16 20:28

我正在使用lxml库来读取我的xml文件。我的代码大致如下。它在lxml2.3 beta1版本下运行得很好,但在lxml2.3版本下却出现了xml语法错误,具体错误信息如下。我查看了这两个版本的发布说明,但没能弄明白是什么导致了这个错误,也不知道该如何修复。如果你遇到过类似的问题或者有任何线索,请帮帮我。

谢谢!!

代码:

from lxml import etree 
def parseXml(context,attribList,elemList):     
   for event, element in context:
       if element.tag in elemList:         
         #read element attributes 
   element.clear()

def main(object):
    ns='{NS}'
    attribList=['name','age','id'] 
    elemList=[ns+'Employee',ns+'Experience',ns+'Employment',ns+'Project',ns+'Award']
    context=etree.iterparse(fullFilePath, events=("start","end")) 
    parseXml(context,attribList,elemList)

错误信息:

文件 "iterparse.pxi",第478行,在 lxml.etree.iterparse.next (src/lxml/lxml.etree.c:95348) 文件 "iterparse.pxi",第530行,在 lxml.etree.iterparse._read_more_events (src/lxml/lxml.etree.c:95886) 文件 "parser.pxi",第585行,在 lxml.etree._raiseParseError (src/lxml/lxml.etree.c:71955) XMLSyntaxError: 找不到命名空间默认前缀,第545行,第73列

xml示例 -

<root xmlns='NS'>
 <Employee Name="Mr.ZZ" Age="30">
  <Experience TotalYears="10" StartDate="2000-01-01" EndDate="2010-12-12">
   <Employment id = "1" EndTime="ABC" StartDate="2000-01-01" EndDate="2002-12-12">
     <Project Name="ABC_1" Team="4">
     </Project>
   </Employment>
   <Employment id = "2" EndTime="XYZ" StartDate="2003-01-01" EndDate="2010-12-12">
    <PromotionStatus>Manager</PromotionStatus>
    <Project Name="XYZ_1" Team="7">
     <Award>Star Team Member</Award>
    </Project>
   </Employment>
  </Experience>
 </Employee>
</root> 

在根节点内,'Employee'是重复的。错误发生在解析器已经正确处理了许多员工数据之后。

编辑 1: 在捕获异常时,我捕获到了以下内容:

WARNING:NAMESPACE:NS_ERR_UNDEFINED_NAMESPACE: Namespace default prefix was not found

2 个回答

0

默认命名空间的问题通常出现在你尝试使用 xpath 表达式的时候。就像你提供的例子那样,如果只是解析数据流,版本 2.3.0 应该可以正常工作,即使没有命名的默认命名空间。

也许你应该发一个最小的 xml 文件,这个文件能引发这个错误(第 545 行的错误在文件里已经很深了)。

2

好的,我终于搞明白发生了什么事。根据一个很好的建议,我开始清理用过的元素,但我把所有元素都清理了,包括根节点。根节点就是那个带有默认命名空间前缀的节点,这个前缀会应用到根节点下面的所有节点上。因为我把根节点清理掉了,所以它下面的子元素就不再有这个默认的命名空间前缀了。之前的版本对此比较宽容,但最新的版本在这方面就严格多了。

直到我读完XML之前都不清理根元素,这样就解决了我的问题。

撰写回答