Получение библиотеки pythons ElementTree для сохранения пространств имен проанализированных файлов

Мне нужно манипулировать XML-файлами с помощью python-Script для создания тестовых данных для устаревшего приложения. Это означает открыть файл, прочитать его, выполнить некоторые манипуляции и записать в файл. Чтобы целевая система могла обрабатывать мои пространства имен testdata, ДОЛЖНО быть сохранено в их первоначальной форме. Файлы, которые я обрабатываю, содержат такие строки, как xmlns:EHC-1234="URI".

Поскольку библиотека elementTree обычно заменяет каждое пространство имен новым, например ns0:ns1: и т. д., я придумал вот такую ​​уродливую штуку:

            #hack to preserve namespaces
            for elem in ET.iterparse(xmlFile):
                    try:
                            try:
                                    if elem[0][0] == "E":
                                            ET.register_namespace(elem[0], elem[1])
                            except TypeError:
                                    pass
                    except IndexError:
                            pass

            tree = ET.parse(xmlFile)
            #do stuff
            .....
            tree.write(filename, xml_declaration=True, encoding='utf-8', method="xml")

Очевидно, что это быстро и грязно. (Обратите внимание, что мне нужно проглотить все виды ошибок, потому что есть много других тегов, а не только определения пространства имен в файле, который я анализирую. Мне также приходится дважды анализировать мой файл, потому что пространства имен должны быть зарегистрированы перед разбором файла. чтобы действовать при повторной записи в файл.). Интересно, однако, как можно было бы сделать это в хороший способ? У тебя есть идеи? Я пытался погуглить, но не нашел простого решения, так что, возможно, где-то здесь есть «лучшая практика» :)

Спасибо и здоровья Мише


person Mischa Obrecht    schedule 05.03.2015    source источник
comment
Разве нет предопределенного набора пространств имен? Или вы постоянно получаете XML-документы с ранее неизвестными пространствами имен?   -  person mzjn    schedule 08.03.2015
comment
Я получаю 8 разных типов XML с разными наборами пространств имен. В принципе, я мог бы вручную добавить их все в namespace_map, но мне это тоже не кажется элегантным решением.   -  person Mischa Obrecht    schedule 09.03.2015


Ответы (1)


Это может быть не лучший способ сделать это, но я в основном выполняю тот же самый interparse, ища только события «start-ns» (начальное пространство имен), а затем регистрирую пространство имен всякий раз, когда вижу одно начало.

p_infile — это переменная, содержащая имя файла, который я собираюсь разобрать.

«События» должны быть списком, но нам нужны только «start-ns».

events = "start-ns", 
for event, elem in ET.iterparse(p_infile, events):
   if event == "start-ns":
       ET.register_namespace(elem[0], elem[1])
       print("registered element " + str(elem))

Тест «if event == start-ns», очевидно, избыточен, но если я хочу позже делать другие вещи с другими событиями, такими как «start» или «end-ns», у меня есть структура. Итак, без самых кратких слов я могу понять:

events = "start-ns", 
for event, elem in ET.iterparse(p_infile, events):
    ET.register_namespace(elem[0], elem[1])

Я провел ограниченное тестирование этого с XML-файлами с одним пространством имен, будьте внимательны.

person NEight    schedule 04.04.2018