lxml:向父元素添加多个混合内容(文本+元素)子节点
lxml: adding multiple mixed content (text + elements) child nodes to a parent element
使用 lxml.etree
,我正在尝试构建一个 XML 文档,其中一些元素可能具有以下形式:
<foo>
There is some text here
<bar>and then a nested child element</bar>
And then some more text
</foo>
我不知道有多少个子节点以及其中哪些是文本节点还是元素。这是通过遍历输入列表并根据列表中每个项目的类型来构建的,决定我是要附加文本节点还是元素。
例如:
parent = etree.Element('foo')
for item in input_data:
if isinstance(item, str):
# Append a text node (???)
pass
else:
parent.append(etree.Element(item['type'], item['text']))
显然设置 .text
不会像我想要的那样混合内容。我知道 lxml.etree
没有我可以附加的“文本节点元素”,我可以使用 .tail
将文本附加到最后一个子元素。然而,为此使用 .tail
似乎非常麻烦,因为我必须跟踪最后一个元素,并检查我是否需要调用 append()
来添加新元素或 .text
来设置第一个文本子节点或在最后一个项目上使用 .tail
以在其后设置一些文本。
在 lxml
中是否有更简洁的方法将混合内容附加到父元素?
一种方法是使用生成器 API,例如
from lxml import etree as ET
from lxml.builder import E
foo = E.foo(*[item if isinstance(item, str) else E(item['type'], item['text']) for item in ['There is some text here', { 'type' : 'bar', 'text' : 'and then a nested child element'}, 'And then some more text']])
然后 ET.tostring(foo)
给出:b'<foo>There is some text here<bar>and then a nested child element</bar>And then some more text</foo>'
.
当然,鉴于您的 input_data
,foo
的构造将简单地读取
foo = E.foo(*[item if isinstance(item, str) else E(item['type'], item['text']) for item in input_data])
使用 lxml.etree
,我正在尝试构建一个 XML 文档,其中一些元素可能具有以下形式:
<foo>
There is some text here
<bar>and then a nested child element</bar>
And then some more text
</foo>
我不知道有多少个子节点以及其中哪些是文本节点还是元素。这是通过遍历输入列表并根据列表中每个项目的类型来构建的,决定我是要附加文本节点还是元素。
例如:
parent = etree.Element('foo')
for item in input_data:
if isinstance(item, str):
# Append a text node (???)
pass
else:
parent.append(etree.Element(item['type'], item['text']))
显然设置 .text
不会像我想要的那样混合内容。我知道 lxml.etree
没有我可以附加的“文本节点元素”,我可以使用 .tail
将文本附加到最后一个子元素。然而,为此使用 .tail
似乎非常麻烦,因为我必须跟踪最后一个元素,并检查我是否需要调用 append()
来添加新元素或 .text
来设置第一个文本子节点或在最后一个项目上使用 .tail
以在其后设置一些文本。
在 lxml
中是否有更简洁的方法将混合内容附加到父元素?
一种方法是使用生成器 API,例如
from lxml import etree as ET
from lxml.builder import E
foo = E.foo(*[item if isinstance(item, str) else E(item['type'], item['text']) for item in ['There is some text here', { 'type' : 'bar', 'text' : 'and then a nested child element'}, 'And then some more text']])
然后 ET.tostring(foo)
给出:b'<foo>There is some text here<bar>and then a nested child element</bar>And then some more text</foo>'
.
当然,鉴于您的 input_data
,foo
的构造将简单地读取
foo = E.foo(*[item if isinstance(item, str) else E(item['type'], item['text']) for item in input_data])