Извлечь часть XML без использования tostring в Python

Скажем, у меня есть такой XML-код:

<a>
 <na:Data xmlns:na="http://some_site.com#" Ref="http://another_site.com" 
  Key="value">
  <b>
  <c>some_c_attrib</c>
  <d>some_d_attrib</d>
  <e>some_e_attrib</e>
   <f>some_f_attrib</f>
   <g>some_g_attrib</g>
  </b>
  <h>
   <i>some_i_attrib</i>
   <j>some_j_attrib</j>
  </h>
 </na:Data>
 <da:Newtag xmlns:da="http://new_site.com">
  <k name="http://new_new_site.com"/>

И после этого есть еще несколько строк. Я проанализировал XML с помощью ET.parse(FILENAME) а затем записал его в новый файл, используя write_c14n("new.xml"), Теперь я хочу извлечь часть этого new.xml в другой XML-файл, где я просто хочу, чтобы часть начиналась с <na:Data xmlns:na="http://some_site.com#" Ref="http://another_site.com" Key="value"> и заканчивается в </h>,

Однако я не хочу использовать tostring() так как он не сохраняет канонизацию XML, полученную с помощью write_c14n(), Мне было интересно, поможет ли копирование только этой части из new.xml и запись ее в другой xml, но я предполагаю, что она добавляет несколько дополнительных строк между ними, а также не сохраняет формат xml как есть.

Я опробовал следующие способы:

Таким образом я попытался создать еще один XML с новым корнем как <na:Data xmlns:na="http://some_site.com#" Ref="http://another_site.com" Key="value">:

from lxml import etree
from io import StringIO, BytesIO
import xml.etree.ElementTree as et
import xml.etree.ElementTree as xml
from xml.etree import ElementTree as ET

tree = etree.parse('file_location/file_to_read.xml')
root = tree.getroot()

sub_root = etree.Element('{http://some_site.com#}Data')
for node in root.find('.//na:Data', namespaces = {'na':'http://some_site.com#'}).getchildren():


    sub_root.append(node.element)

new_tree = etree.ElementTree(sub_root)

Мне просто нужен объект new_tree, чтобы я мог использовать его как new_tree. Однако, если я распечатаю вышеупомянутое new_tree, используя tostring() [то есть печать etree.tostring(root_tree,pretty_print=True)] это вывод, который я получаю:

<ns0:Data xmlns:ns0="http://some_site.com#"><b>
 <c>some_c_attrib</c>
 <d>some_d_attrib</d>
 <e>some_e_attrib</e>
  <f>some_f_attrib</f>
  <g>some_g_attrib</g>
 </b>
 <h>
  <i>some_i_attrib</i>
  <j>some_j_attrib</j>
 </h>
</ns0:Data>

Как вы можете видеть na:Data был заменен ns0:Data а также его ключи и значения (Ref="http://another_site.com" Key="value") не хватает. Мне нужен способ, который может извлечь часть XML, как это со всеми атрибутами, ключами и значениями.

1 ответ

Решение

Нет необходимости создавать новые элементы. Просто проанализируйте оригинальный файл XML, распакуйте na:Data дочерний элемент и запишите его в новый файл.

from lxml import etree

tree = etree.parse('file_location/file_to_read.xml')
Data = tree.find('.//na:Data', namespaces={'na':'http://some_site.com#'})
etree.ElementTree(Data).write_c14n("new.xml")
Другие вопросы по тегам