2015-04-29 3 views
1

У меня есть большой XML-файл, который выглядит как один ниже. Я поставил только часть его, так как это> 2gb, так что вы видите структуру. В основном все SubNetwork parents имеют ту же структуру, что и я, показанный ниже. Я хочу, чтобы извлечь только часть этого xml-файла с помощью <ManagedElementId string="xxxx" /> (где xxx i - входная переменная). Вот мой код и XML:Извлечь часть файла xml с python etree

<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 

Как сказал там numerues число <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> 

Итак, я хочу, чтобы найти все ManagedElementIds, как указано в list_of_xxx, и их родителей ManagedElement и SubNetwork, и записать их, как указано выше. Каждый MangedElementid должен быть закрыт вместе с родителями. Я использую python 2.6 без lxml, так как я не имею права устанавливать его.

+0

Что не работает о коде образца вы публикуемую? –

+0

ну, я не получаю родителей, подсети и ManagedElement, и я хочу, чтобы это было на моем выходе. – user3319356

ответ

2

Распаковка часть из XML в том смысле, что эта часть существует в исходном XML должен быть тривиальным. Например, получение ManagedElement s с определенным ManagedElementId, которое вас интересует, будет легким. Но здесь вы, кажется, хотите, чтобы они были завернуты в родительский узел SubNetwork.

В исходном XML, SubNetwork содержит сочетание элементов, которые вы хотите получить и другие элементы, которые вы хотите, чтобы раздеть от результата, так что на самом деле не таких SubNetwork, содержащих толькоManagedElement узлов, которые вы хотите.

Мы можем подойти к этому путем извлечения ManagedElement узлов из исходного XML, и добавить их в реконструированном родительский узел 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) 
+1

Спасибо, он отлично работает. Я только что заменил ET.create с помощью ET.Element. – user3319356

+0

мой плохой, это была ошибка копирования-вставки, когда я пытался изменить свой рабочий код в соответствии с вашим существующим кодом. Исправлено: – har07

+0

Мне пришлось задать новый вопрос, так как на python 2.6 он не работает. http://stackoverflow.com/questions/30000251/python-2-6-etree-not-working – user3319356

Смежные вопросы