Вам нужно дать элементу speak
пространство имен, а также его атрибут version
, который обычно настраивается атрибутом xmlns="..."
. Используйте для этого * квалифицированный формат имени {<namespaceuri>}<tagname>
, как и для атрибута xml:lang
:
xml_body = ElementTree.Element('{https://www.w3.org/2001/10/synthesis}speak')
xml_body.set('{https://www.w3.org/2001/10/synthesis}version', '1.0')
xml_body.set('{http://www.w3.org/XML/1998/namespace}lang', 'en-us')
Вы также можете добавить атрибуты в виде словаря, передаваемого в качестве второго аргумента:
xml_body = ElementTree.Element(
'{https://www.w3.org/2001/10/synthesis}speak', {
'{https://www.w3.org/2001/10/synthesis}version': '1.0',
'{http://www.w3.org/XML/1998/namespace}lang': 'en-us'
})
Вы не должны установить атрибут xmlns:mstts
, однако! ElementTree добавит этот атрибут автоматически , если необходимо, в зависимости от того, какие пространства имен были использованы в построенном вами дереве XML.
Вы do хотите зарегистрироваться это пространство имен с ElementTree с использованием функции register_namespace()
:
ElementTree.register_namespace('mstts', 'https://www.w3.org/2001/mstts')
Это сообщает ElementTree, что при использовании пространства имен {https://www.w3.org/2001/mstts}
с именами тегов или атрибутами, это при сериализации дерева XML в файл или строку , что это пространство имен должно использовать mstts
в качестве префикса. Если вы не зарегистрируете пространство имен, для вас будет сгенерирован префикс пространства имен (ns0:
, ns1:
и т. Д.). Это приведет к совершенно правильному XML, префиксы пространства имен будут локальными для документации, а префиксы - это просто сокращенные имена для полного URI пространства имен. Любой совместимый синтаксический анализатор XML будет обрабатывать ns0
в качестве префикса для URI пространства имен https://www.w3.org/2001/mstts
точно так же, как при использовании mstts
.
Для пространства имен по умолчанию (например, * 1044). * пространство имен для корневого <speak>
элемента), используйте аргумент default_namespace
для ElementTree.write()
метода .
Мне легче QName()
объектов обрабатывать имена пространственных атрибутов и тегов;вместе с переменными для конкретных пространств имен, что снижает вероятность опечаток. Вот более полный пример , основанный на примере из документации Azure SSML
from xml.etree import ElementTree as ET
from functools import partial
ns = {
"synthesis": "https://www.w3.org/2001/10/synthesis",
"mstts": "https://www.w3.org/2001/mstts",
"xml": "http://www.w3.org/XML/1998/namespace",
}
ET.register_namespace('mstts', ns['mstts'])
synthesis = partial(ET.QName, ns["synthesis"])
mstts = partial(ET.QName, ns["mstts"])
xml_ = partial(ET.QName, ns["xml"])
xml_body = ET.Element(synthesis('speak'), {
synthesis('version'): '1.0',
xml_('lang'): 'en-us',
})
voice = ET.SubElement(xml_body, synthesis('voice'), {
synthesis('name'): 'en-US-JessaNeural'})
express_as = ET.SubElement(voice, mstts('express-as'), {
mstts('type'): 'cheerful'})
express_as.text = "That'd be just amazing!"
root = ET.ElementTree(xml_body)
root.write("filename.xml", encoding="UTF-8", default_namespace=ns["synthesis"])
Приведенный выше код дает следующий XML-код (напечатанный вручную для удобства чтения):
<speak
xmlns="https://www.w3.org/2001/10/synthesis"
xmlns:mstts="https://www.w3.org/2001/mstts"
version="1.0"
xml:lang="en-us">
<voice name="en-US-JessaNeural">
<mstts:express-as mstts:type="cheerful">
That'd be just amazing!
</mstts:express-as>
</voice>
</speak>
Вместо этого вы можете захотеть взглянуть и на external lxml
library , так как он включает lxml.builder.ElementMaker
class , который делает работу с пространствами имен еще проще,
lxml имеет гораздо лучшую поддержку пространства имен в целом, и атрибуты элемента, у которого уже есть пространство имен, не должны быть явно определены самим пространством имен. Вы можете пометить данное сопоставление пространства имен как значение по умолчанию, используя префикс None
в словаре, устанавливающем пространства имен:
from lxml import etree as ET
from lxml.builder import ElementMaker
ns = {
None: "https://www.w3.org/2001/10/synthesis",
"mstts": "https://www.w3.org/2001/mstts",
}
E = ElementMaker(namespace=ns[None], nsmap=ns)
TTS = ElementMaker(namespace=ns['mstts'])
xml_body = E.speak(
{"version": "1.0",
"{http://www.w3.org/XML/1998/namespace}lang": "en-US"},
E.voice(
{"name": "en-US-JessaNeural"},
TTS('express_as',
"That'd be just amazing!",
type="cheerful",
)
)
)
. В приведенном выше примере использование E.tagname(...)
или E('tagname', ...)
создастэлемент с URI пространства имен https://www.w3.org/2001/10/synthesis
, а объект MSTTS
создает теги с URI пространства имен https://www.w3.org/2001/mstts
. Поскольку мы дали E
карту пространства имен с None
отображением на https://www.w3.org/2001/10/synthesis
URI пространства имен, этот URI будет использоваться в качестве пространства имен по умолчанию, а теги и атрибуты в этом пространстве имен не будут иметь префикса.
Выможет передавать атрибуты либо в качестве аргументов ключевого слова (E.tagname(..., attributename="value")
), либо через словарь, передаваемый в качестве позиционного аргумента. Любые содержащиеся элементы могут быть просто добавлены в качестве позиционных аргументов, включая текст. Вы также можете добавить обычные Element
методы (например, Element.append()
, чтобы добавить дочерний элемент, или Element.text = ...
, чтобы указать, что такое текстовое содержимое тега).
Демонстрация с использованием lxml:
>>> from lxml import etree as ET
>>> from lxml.builder import ElementMaker
>>> ns = {
... None: "https://www.w3.org/2001/10/synthesis",
... "mstts": "https://www.w3.org/2001/mstts",
... }
>>> E = ElementMaker(namespace=ns[None], nsmap=ns)
>>> TTS = ElementMaker(namespace=ns['mstts'])
>>> xml_body = E.speak(
... {"version": "1.0",
... "{http://www.w3.org/XML/1998/namespace}lang": "en-US"},
... E.voice(
... {"name": "en-US-JessaNeural"},
... TTS('express_as',
... "That'd be just amazing!",
... type="cheerful",
... )
... )
... )
>>> print(ET.tostring(xml_body, encoding="unicode", pretty_print=True))
<speak xmlns="https://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" version="1.0" xml:lang="en-US">
<voice name="en-US-JessaNeural">
<mstts:express_as type="cheerful">That'd be just amazing!</mstts:express_as>
</voice>
</speak>