Вы перепутали префикс пространства имен wp
с именем тега.Префикс пространства имен - это локальное имя документа для URI пространства имен.wp:title
требует, чтобы синтаксический анализатор искал атрибут xmlns:wp="..."
для поиска самого пространства имен (обычно это URL, но подойдет любая глобально уникальная строка), либо в самом теге, либо в родительском теге.Это соединяет теги с уникальным значением, не делая имен тегов слишком многословными для ввода или чтения.
Вам необходимо предоставить пространство имен и, необязательно, отображение пространства имен (сопоставление коротких имен с полными именами пространства имен) с элементомсоздатель объекта.Предоставленный объект E
по умолчанию не имеет установленной карты пространства имен или пространства имен.Я собираюсь предположить, что здесь wp
является http://wordpress.org/export/1.2/
пространством имен Wordpress, поскольку это кажется наиболее вероятным, хотя может также случиться так, что вы пытаетесь отправить уведомления Windows Phone .
Вместо использования создателя элемента E
по умолчанию создайте свой собственный экземпляр ElementMaker
и передайте ему аргумент namespace
, чтобы сообщить lxml
, к какому URL принадлежит элемент.Чтобы получить правильный префикс для имен ваших элементов, вам также нужно предоставить ему словарь nsmap
, который сопоставляет префиксы с URL-адресами:
from lxml.builder import ElementMaker
namespaces = {"wp": "http://wordpress.org/export/1.2/"}
E = ElementMaker(namespace=namespaces["wp"], nsmap=namespaces)
title = E.title("Value of the wp:title tag")
. При этом создается тег с правильным префиксом, и атрибут xmlns:wp
:
>>> from lxml.builder import ElementMaker
>>> namespaces = {"wp": "http://wordpress.org/export/1.2/"}
>>> E = ElementMaker(namespace=namespaces["wp"], nsmap=namespaces)
>>> title = E.title("Value of the wp:title tag")
>>> etree.tostring(title, encoding="unicode")
'<wp:title xmlns:wp="http://wordpress.org/export/1.2/">Value of the wp:title tag</wp:title>'
Вы можете опустить значение nsmap
, но тогда вы захотите иметь такую карту в элементе parent элементадокумент.В этом случае вы, вероятно, захотите создать отдельные ElementMaker
объекты для каждого пространства имен, которое вам нужно поддерживать, и вы поместите отображение пространства имен nsmap
на самый внешний элемент.При записи документа lxml
затем использует короткие имена повсюду.
Например, для создания документа в формате Wordpress WXR потребуется несколько пространств имен:
from lxml.builder import ElementMaker
namespaces = {
"excerpt": "https://wordpress.org/export/1.2/excerpt/",
"content": "http://purl.org/rss/1.0/modules/content/",
"wfw": "http://wellformedweb.org/CommentAPI/",
"dc": "http://purl.org/dc/elements/1.1/",
"wp": "https://wordpress.org/export/1.2/",
}
RootElement = ElementMaker(nsmap=namespaces)
ExcerptElement = ElementMaker(namespace=namespaces["excerpt"])
ContentElement = ElementMaker(namespace=namespaces["content"])
CommentElement = ElementMaker(namespace=namespaces["wfw"])
DublinCoreElement = ElementMaker(namespace=namespaces["dc"])
ExportElement = ElementMaker(namespace=namespaces["wp"])
, а затем вы создадите документ с
doc = RootElement.rss(
RootElement.channel(
ExportElement.wxr_version("1.2"),
# etc. ...
),
version="2.0"
)
, который, при печати с etree.tostring(doc, pretty_print=True, encoding="unicode")
, выдаст:
<rss xmlns:excerpt="https://wordpress.org/export/1.2/excerpt/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wp="https://wordpress.org/export/1.2/" version="2.0">
<channel>
<wp:wxr_version>1.2</wp:wxr_version>
</channel>
</rss>
Обратите внимание, что только корень <rss>
Элемент имеет атрибуты xmlns
и то, как тег <wp:wxr_version>
использует правильный префикс, хотя мы дали ему только URI пространства имен.
Чтобы привести другой пример, если вы создаете уведомление для плитки Windows Phone,было бы проще.В конце концов, нужно использовать только одно пространство имен:
from lxml.builder import ElementMaker
namespaces = {"wp": "WPNotification"}
E = ElementMaker(namespace=namespaces["wp"], nsmap=namespaces)
notification = E.Notification(
E.Tile(
E.BackgroundImage("https://example.com/someimage.png"),
E.Count("42"),
E.Title("The notification title"),
# ...
)
)
, которое создает
<wp:Notification xmlns:wp="WPNotification">
<wp:Tile>
<wp:BackgroundImage>https://example.com/someimage.png</wp:BackgroundImage>
<wp:Count>42</wp:Count>
<wp:Title>The notification title</wp:Title>
</wp:Tile>
</wp:Notification>
Только самый внешний элемент, <wp:Notification>
, теперь имеет атрибут xmlns:wp
,Все остальные элементы должны включать только префикс wp:
.
Обратите внимание, что префикс полностью зависит от вас и даже необязательно .Именно URI пространства имен является реальным ключом для уникальной идентификации элементов в разных документах XML.Если вы вместо этого использовали E = ElementMaker(namespace="WPNotification", nsmap={None: "WPNotification"})
и сгенерировали элемент верхнего уровня с <Notification xmlns="WPNotification">
, у вас все еще есть совершенно законный документ XML, который, согласно стандарту XML, имеет точно такое же значение.