使用 python etree 提取部分 xml 文件

Extract part of xml file with python etree

我有一个很大的 xml 文件,如下所示。我只放了它的一部分,因为它大于 2gb,所以你可以看到结构。基本上所有 SubNetwork parents 都具有与我在下面显示的结构相同的结构。我想要做的是使用 <ManagedElementId string="xxxx" />(其中 xxx i 输入变量)仅提取此 xml 文件的一部分。这是我的代码 xml:

<Create> 
<SubNetwork networkType="GSM" userLabel="BSC">
.
.
</SubNetwork>
<SubNetwork networkType="WCDMA" userLabel="RNC01">
.
.
</SubNetwork>
<SubNetwork networkType="IPRAN" userLabel="IPRAN">
.
.
</SubNetwork>
<SubNetwork networkType="WCDMA" userLabel="RNC02">
                  <ManagedElement sourceType="CELLO">
                     <ManagedElementId string="3GALPAS" />
                     <primaryType type="RBS" />
                   .
                   .
                  </ManagedElement>
                  <ManagedElement sourceType="CELLO">
                     <ManagedElementId string="3GTUTI" />
                     <primaryType type="RBS" />
                   .
                   .
                  </ManagedElement>
                    <ManagedElement sourceType="CELLO">
                     <ManagedElementId string="3GHHH" />
                     <primaryType type="RBS" />
                   .
                   .
                  </ManagedElement>
</SubNetwork>
</Create> 

和代码

from xml.etree import ElementTree
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import XML, fromstring, tostring
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement
from xml.etree.ElementTree import Element, SubElement, Comment


with open(r"C:\Users\etihkru\Desktop\h4.xml", 'rt') as f:
   root = ET.parse(f)
   tree=root.getroot()
   with open(r"C:\Users\etihkru\Desktop\list_of_xxx", 'r') as f2:
        for line in f2:
             line=line.rstrip()
             line1='"' + line + '"'
             xp_str1 = str(('.//ManagedElementId[@string='))
             xp_str2 = str("]/../../")
             str_elem = xp_str1 + line1 + xp_str2 
             for item in tree.findall(str_elem):
                    print ET.tostring(item)

文件list_of_xxx如下:

3GALPAS
3GTUTI

如前所述,有 <ManagedElementId string=/> 个数字,我只想提取 list_of_xxx.

中的数字

所以我想要如下输出:

<SubNetwork networkType="WCDMA" userLabel="RNC02">
                  <ManagedElement sourceType="CELLO">
                     <ManagedElementId string="3GALPAS" />
                     <primaryType type="RBS" />
                   .
                   .
                  </ManagedElement>
</SubNetwork>
<SubNetwork networkType="WCDMA" userLabel="RNC02">
                  <ManagedElement sourceType="CELLO">
                     <ManagedElementId string="3GTUTI" />
                     <primaryType type="RBS" />
                   .
                   .
                  </ManagedElement>
</SubNetwork>

所以,我想找到 list_of_xxx 中给出的所有 ManagedElementIds,以及它们的 parents ManagedElementSubNetwork,并将它们写成给定的多于。如前所述,每个 MangedElementid 都应该用 parents 结束。我正在使用没有 lxml 的 python 2.6,因为我无权安装它。

提取 XML 的 part 在某种意义上说 part 存在于源 XML 中应该是琐碎的。例如,获取包含您感兴趣的某些 ManagedElementIdManagedElement 将很容易。但是在这里您似乎希望它们包含在 SubNetwork 父节点中。

在源码 XML 中,SubNetwork 包含您想要获取的元素和您想要从结果中去除的其他元素的混合,因此实际上没有这样的 SubNetwork 包含只有ManagedElement个你想要的节点。

我们可以通过从源 XML 中提取 ManagedElement 节点来解决这个问题,并将它们添加到重构的父 SubNetwork 节点:

.....
.....
for line in f2:
    line = line.rstrip()
    #get all subnet nodes containing certain ManagedElementId
    subnet_path = ".//ManagedElementId[@string='{0}']/../.."
    subnet_path = subnet_path.format(line)
    for subnet in tree.findall(subnet_path):
        #reconstruct subnet node:
        parent = ET.Element(subnet.tag, attrib=subnet.attrib)
        #path to find all ManagedElement containing certain ManagedElementId
        content_path = ".//ManagedElementId[@string='{0}']/..".format(line)
        #append all ManagedElement found to the new subnet:
        for content in subnet.findall(content_path):
            parent.append(content)
        #print new subnet:
        print ET.tostring(parent)