2015-07-21 78 views
3

我读的数百个XML文件,并与xml.etree.ElementTree解析他们。Python中的XML - 处理未关闭的标记

快速背景只是fwiw: 这些XML文件是在一个完全有效的,但不知何故,当处理它们的历史上,我的过程复制/粘贴它们可能已经损坏它们。 (原来这是一个冲动的问题/声明不关闭,如果你在意,请参阅我在调查中得到的好帮助...... Python shutil copyfile - missing last few lines)。

反正回到这个问题的要点。
我仍想在第一100,000行或使这些文件它们是有效的XML的阅读。这些文件只会丢失6MB文件的最后4或5KB。正如前面提到的那样,该文件只是“切断”。它看起来像这样:

</Maintag> 




<Maintag> 
    <Change_type>NQ</Change_type> 
    <Name>Atlas</Name> 
    <Test>ATLS</Test> 
    <Other>NYSE</Other> 
    <Scheduled_E 

在哪里(也许明显)Scheduled_E是什么应该是另一个属性开始,< .Scheduled_Event>,说。但是文件被缩短了中间标签。再次,在该文件中这点之前,有几千个“好”“Maintag”的条目,我想在阅读,接受截止条目(显然任何应该来后)为不可恢复的失败。

处理这个问题的一个简单但不完整的方法可能是简单地 - 预处理XML - 在文件中查找字符串< ./Maintag>的最后一个实例,并替换后面的内容(将在一些点)与'开放'标签。再次,这至少让我处理仍然存在并且有效的东西。

如果有人想帮助我之类的字符串替换,那么FWIW开幕标签:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<FirstTag> 
    <Source FileName="myfile"> 

我希望,甚至比这更容易,有可能是一个ElementTree的或beautifulsoup或其他处理这种情况的方式......我做了大量的搜索,没有任何东西看起来简单/明显。

感谢

+0

没有DOM解析器能够处理不完整的(因此不正确的)XML。 Sax解析器在达到“截止点”时会崩溃,但您可以使用一个捕获异常并实现“无家可归者的方法”。 “无家可归的人的方法”的 –

+0

OP的解决方案似乎更像是一个创可贴比实际解决问题,这是IMO如何读取并解析XML文件,而不会丢失内容。否则,如果你只是在任意数量的字节后删除内容,那么解析意义究竟有什么意义呢? – shoover

+0

简单的方法:'echo'>'>> myfile.xml'。 – refi64

回答

2

对于处理未关闭的元素 - 或者令牌在本questioin-的标题,我建议你去尝试lxmllxmlXMLParser具有recover选项,documented为:

恢复 - 努力突破XML解析

例如,给一个破碎的XML如下:

from lxml import etree 

xml = """ 
<root> 
    <Maintag> 
     <Change_type>NQ</Change_type> 
     <Name>Atlas</Name> 
     <Test>ATLS</Test> 
     <Other>NYSE</Other> 
     <Scheduled_E 
""" 
parser = etree.XMLParser(recover=True) 
doc = etree.fromstring(xml, parser=parser) 
print(etree.tostring(doc)) 

的作为印刷用上述代码回收XML是如下:

<root> 
    <Maintag> 
     <Change_type>NQ</Change_type> 
     <Name>Atlas</Name> 
     <Test>ATLS</Test> 
     <Other>NYSE</Other> 
     <Scheduled_E/></Maintag></root> 
+0

感谢您的关注。在您的示例x​​ml字符串中,最后包含'关闭'<./root>标记。要清楚,我错过了所有结束标记,因为该文件在它应该之前只删除了几KB。 (我在创建文件时遇到了一个冲突问题=()。(如果我可以将那些'结束标记'称为更具技术性的东西,请参阅我的词汇表) – 10mjg

+0

@ 10mjg我刚试过''和'lxml '还是能对付它,答案在这种情况下,相应的更新 – har07

+0

好,这听起来似乎会工作,我会测试这个明天。非常感谢你!我 – 10mjg