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

Мне нужно манипулировать XML-файлами с помощью Python-Script для генерации тестовых данных для унаследованного приложения. Это значит, открыть файл, прочитать его, сделать некоторые манипуляции и записать в файл. Чтобы целевая система могла обрабатывать мои пространства имен тестовых данных, ДОЛЖНЫ быть сохранены в их первоначальной форме. Файлы, которые я обрабатываю, содержат строки вроде 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")

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

Спасибо и ура Миша

1 ответ

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

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

"events" должен быть списком, но нам нужны только "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-файлами с одним пространством имен, caveat emptor.

Другие вопросы по тегам