Найти - Пользователи
Полная версия: сформировать пространство имен XML файла
Начало » Python для новичков » сформировать пространство имен XML файла
1
saicat
Доброго времени суток всем!

Ребята, подскажите, пожалуйста, как правильно определить пространство имен в XML файле при помощи lxml.

Мне нужен вот такой результат на выходе:
<?xml version=“1.0” encoding=“UTF-8”?>
<notificationRequest xmlns="http://www.meinpaket.de/xsd/dietmar/1.0/orders
xmlns:common=”http://www.meinpaket.de/xsd/dietmar/1.0/common
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
version=”1.0">

Вот код, при помощи которого я генерирую XML:
import lxml.etree
import os
xmlns = "http://www.meinpaket.de/xsd/dietmar/1.0/orders"
xmlns_xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns_common = "http://www.meinpaket.de/xsd/dietmar/1.0/common"
NSMAP = {None: xmlns, 'xsi': xmlns_xsi}
root = lxml.etree.Element('notificationRequest', nsmap=NSMAP)
root = lxml.etree.Element('notificationRequest')
root.set('xmlns', xmlns)
root.set('version', '1.0')
root.set('{http://www.w3.org/2001/XMLSchema-instance}common', xmlns_common)
head = lxml.etree.SubElement(root, 'data')
handle = lxml.etree.tostring(root, pretty_print=True, encoding='utf-8', xml_declaration=True)
with open(os.path.join(os.getcwd(), "text.xml"), "wb") as f:
    f.write(handle)

Результат работы:
<?xml version='1.0' encoding='utf-8'?>
<notificationRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance“ xmlns=”http://www.meinpaket.de/xsd/dietmar/1.0/orders“ version=”1.0“ xsi:common=”http://www.meinpaket.de/xsd/dietmar/1.0/common">

в этом случае правильно прописывается xmlns:xsi, но common определяется с префиксом xsi, а не xmlns, как требуется.
Если же поменять URI на xmlns у аттрибута common:

root.set('{http://www.meinpaket.de/xsd/dietmar/1.0/orders}common', xmlns_common)

то получается полная ерунда:
<?xml version='1.0' encoding='utf-8'?>
<notificationRequest xmlns:ns0="http://www.meinpaket.de/xsd/dietmar/1.0/orders“ xmlns=”http://www.meinpaket.de/xsd/dietmar/1.0/orders“ version=”1.0“ ns0:common=”http://www.meinpaket.de/xsd/dietmar/1.0/common">
Появляется префикс ns0, а определение xmlns:xsi исчезает вовсе.
Буду благодарен, если поможете разобраться. Сильно не бейте, если накосячил, пайтон только начал изучать. Язык нравится, но нужно к некоторым вещам выработать привычку)
Спасибо!
GreyZmeem
У вас в NSMAP указаны не все namespace.

from lxml import etree
nsmap = {
 None: 'http://www.meinpaket.de/xsd/dietmar/1.0/orders',
 'common': 'http://www.meinpaket.de/xsd/dietmar/1.0/common',
 'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
}
e = etree.Element('notificationRequest', nsmap=nsmap)
print etree.tostring(e)
'<notificationRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:common="http://www.meinpaket.de/xsd/dietmar/1.0/common" xmlns="http://www.meinpaket.de/xsd/dietmar/1.0/orders"/>'
saicat
GreyZmeem, спасибо огромное!

Я пробовал такой вариант решения, но он у меня не заработал. Теперь понимаю почему - отсутствовала запятая после последнего элемента словаря NSMAP. У меня он вот так выглядел:

NSMAP = { None: 'http://www.meinpaket.de/xsd/dietmar/1.0/orders', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'common': 'http://www.meinpaket.de/xsd/dietmar/1.0/common'}

Так не работало и
print(root.nsmap)
показывал наличие только двух элементов в NSMAP. Я и подумал, грешным делом, что их можно определить всего два - дефолтный и один “именной”.

Спасибо еще раз!
GreyZmeem
Скорей всего вы просто где-то ошиблись. Запятая ни на что не влияет
saicat
Действительно, теперь и без запятой работает… Чудеса)))

Скорее всего, действительно где-то еще ошибся.

Спасибо еще раз!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB