使用xmltree解析大型pythonxml

使用xmltree解析大型pythonxml,python,xml,grep,lxml,elementtree,Python,Xml,Grep,Lxml,Elementtree,我有一个python脚本,可以解析巨大的xml文件(最大的是446MB) 这就是我的xml的样子: <?xml version="1.0" encoding="utf-8"?> <MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml

我有一个python脚本,可以解析巨大的xml文件(最大的是446MB)

这就是我的xml的样子:

<?xml version="1.0" encoding="utf-8"?>
<MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml/data/litsmlv2">
  <Aliases authority="OPP" xmlns="http://www.example.org/yml/data/commonv2">
     <Description>myData</Description>
     <Identifier>43hhjh87n4nm</Identifier>
  </Aliases>
  <RollNo uom="kPa">39979172.201167159</RollNo>
  <PersonName>Miracle Smith</PersonName>
  <Date>2017-06-02T01:10:32-05:00</Date>
....
我的XML非常好,没有额外的内容。似乎是大文件解析导致了错误。 我已经研究了iterparse(),但对于我想要实现的目标来说似乎很复杂,因为它提供了对整个DOM的解析,而我只需要根下的一个标记。还有,难道没有给我一个很好的示例来通过标记名获得正确的值吗

我应该使用正则表达式解析还是grep/awk方法来实现这一点?或者对我的代码进行任何调整都可以让我在这些巨大的文件中获得人名

更新: 尝试了这个示例,它似乎从xml打印了整个世界,除了我的标记

iterparse是否从文件的底部到顶部读取?在这种情况下,需要很长时间才能到达顶部,即我的人名标签?我试着将下面的行改为end to start events=(“end”,“start”),它也做了同样的事情

path = []
for event, elem in ET.iterparse('D:\\mystage\\2-80ea-005056.xml', events=("start", "end")):
    if event == 'start':
            path.append(elem.tag)
    elif event == 'end':
            # process the tag
            print elem.text  // prints whole world 
            if elem.tag == 'PersonName':
                print elem.text
            path.pop()

在这种情况下,Iterparse并不难使用

temp.xml
是您的问题中显示的文件,其末尾以一行形式显示

如果愿意的话,可以将
source=
看作一个样板文件,它解析xml文件并逐元素返回它的块,指示块是元素的“开始”还是“结束”,并提供有关元素的信息

在这种情况下,我们只需要考虑“开始”事件。我们观察“PersonName”标签并提取它们的文本。在xml文件中找到了唯一这样的项之后,我们放弃了处理

>>> from xml.etree import ElementTree
>>> source = iter(ElementTree.iterparse('temp.xml', events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
... 
'Miracle Smith'
编辑,回应评论中的问题:

通常您不会这样做,因为
iterparse
用于大块xml。但是,通过将字符串包装在
StringIO
对象中,可以使用
iterparse
对其进行处理

>>> from xml.etree import ElementTree
>>> from io import StringIO
>>> xml = StringIO('''\
... <?xml version="1.0" encoding="utf-8"?>
... <MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml/data/litsmlv2">
...   <Aliases authority="OPP" xmlns="http://www.example.org/yml/data/commonv2">
...        <Description>myData</Description>
...             <Identifier>43hhjh87n4nm</Identifier>
...               </Aliases>
...                 <RollNo uom="kPa">39979172.201167159</RollNo>
...                   <PersonName>Miracle Smith</PersonName>
...                     <Date>2017-06-02T01:10:32-05:00</Date>
... </MyRoot>''')
>>> source = iter(ElementTree.iterparse(xml, events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
...     
'Miracle Smith'
>来自xml.etree导入元素树
>>>从io导入StringIO
>>>xml=StringIO(“”)\
... 
... 
...   
…我的数据
…43HHHJH87N4nm
...               
...                 39979172.201167159
…奇迹史密斯
…2017-06-02T01:10:32-05:00
... ''')
>>>source=iter(ElementTree.iterparse(xml,events=('start','end'))
>>>对于_事件,源中的_元素:
...     如果一个_事件=='start'和一个_元素.tag.endswith('PersonName'):
...         一个元素
...         打破
...     
“奇迹史密斯”

在这种情况下使用Iterparse并不难

temp.xml
是您的问题中显示的文件,其末尾以一行形式显示

如果愿意的话,可以将
source=
看作一个样板文件,它解析xml文件并逐元素返回它的块,指示块是元素的“开始”还是“结束”,并提供有关元素的信息

在这种情况下,我们只需要考虑“开始”事件。我们观察“PersonName”标签并提取它们的文本。在xml文件中找到了唯一这样的项之后,我们放弃了处理

>>> from xml.etree import ElementTree
>>> source = iter(ElementTree.iterparse('temp.xml', events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
... 
'Miracle Smith'
编辑,回应评论中的问题:

通常您不会这样做,因为
iterparse
用于大块xml。但是,通过将字符串包装在
StringIO
对象中,可以使用
iterparse
对其进行处理

>>> from xml.etree import ElementTree
>>> from io import StringIO
>>> xml = StringIO('''\
... <?xml version="1.0" encoding="utf-8"?>
... <MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml/data/litsmlv2">
...   <Aliases authority="OPP" xmlns="http://www.example.org/yml/data/commonv2">
...        <Description>myData</Description>
...             <Identifier>43hhjh87n4nm</Identifier>
...               </Aliases>
...                 <RollNo uom="kPa">39979172.201167159</RollNo>
...                   <PersonName>Miracle Smith</PersonName>
...                     <Date>2017-06-02T01:10:32-05:00</Date>
... </MyRoot>''')
>>> source = iter(ElementTree.iterparse(xml, events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
...     
'Miracle Smith'
>来自xml.etree导入元素树
>>>从io导入StringIO
>>>xml=StringIO(“”)\
... 
... 
...   
…我的数据
…43HHHJH87N4nm
...               
...                 39979172.201167159
…奇迹史密斯
…2017-06-02T01:10:32-05:00
... ''')
>>>source=iter(ElementTree.iterparse(xml,events=('start','end'))
>>>对于_事件,源中的_元素:
...     如果一个_事件=='start'和一个_元素.tag.endswith('PersonName'):
...         一个元素
...         打破
...     
“奇迹史密斯”

如果您不需要浏览xml的结构(例如,您不关心标记的父项是什么),并且只关心这个条目,那么regex可能是一个更好的解决方案。如果您的所有案例都像您发布的示例一样,您甚至可以做一些非常懒惰的事情,比如:matches=[line for line in open('myfile','r')If line.strip().startswith('')。这是假设您的xml文件行与示例中的换行符一起拆分。谢谢!我会试试看。一个XML解决方案也可以很好地考虑将来的想法。是的,如果这将变得更加复杂,投入时间来理解迭代分析是有意义的。我想我曾在维基百科的转储中使用过它,虽然使用起来有点困难,但最终还是值得的。@AndreasGrivas每个文件只有一行,从错误
第1行第
列中可以看出。我会使用
(?@bulbus很好的一点,忽略了这一点,感谢.regex的帮助:)如果您不需要导航xml的结构(例如,您不关心标记的父项是什么),并且只关心这个条目,那么regex可能是一个更好的解决方案。如果您的所有案例都像您发布的示例一样,您甚至可以做一些非常懒惰的事情,比如:matches=[line for line in open('myfile','r')If line.strip().startswith('')。这是假设您的xml文件行与示例中的换行符一起拆分。谢谢!我会试试看。一个XML解决方案也可以很好地考虑将来的想法。是的,如果这将变得更加复杂,投入时间来理解迭代分析是有意义的。我想我曾在维基百科的转储中使用过它,虽然使用起来有点困难,但最终还是值得的。@AndreasGrivas每个文件只有一行,从错误
第1行第
列中可以看出。我会用
做一个正则表达式(?@bulbus很好,错过了这一点,谢谢。正则表达式拯救:)B