lxml:不解析子树,而是将其视为二进制内容
lxml: Do not parse subtree but treat as binary content
我正在处理 XML 内容,其中包含的元素可能包含格式不正确的 XML/markup-like(例如 HTML)文本内容。例如:
<root>
<data>
<x>foo<y>bar</y>
</data>
<data>
<z>foo<y>bar</y>
</data>
</root>
目标:我希望lxml.etree
不要尝试将data
元素下的任何内容解析为XML,而只是[=56] =] 它是 bytes
或 str
(可以是 elem.text
)。
文件很大,我想用lxml.etree.iterparse
提取在data
中找到的内容-
元素。
初始想法:获取元素内容(在本例中包含 data
开始和结束标记)的一种直接方法可能是:
data = BytesIO(b"""
<root>
<data>
<x>foo<y>bar</y>
</data>
<data>
<z>foo<y>bar</y>
</data>
</root>
""")
from lxml import etree
# see below why html=True
context = etree.iterparse(data, events=("end",), tag=("data",), html=True)
contents = [] # I don't keep lists in the "real" application
for event, elem in context:
contents.append(etree.tostring(elem)) # get back the full content underneath data
问题 lxml.etree
可以 运行 解析 data
的子项(例如:我已经当 html
数据存储在 data
下时,使用 html=True
不会 运行 出现问题)。我知道 lxml
中有 custom element classes,但根据我对文档的理解,它们不会改变 lxml.etree
由 libxml2
) 规定的解析行为。
有什么简单的方法可以告诉 lxml
不要尝试将元素内容解析为子元素。应用程序本身受益于其他 lxml
功能,如果我单独为 data
编写自定义提取器,我将不得不复制这些功能。
或者是否可以使用 XSLT 首先转换输入以在 lxml
中进行处理,然后再 link 返回数据?
这是否按预期工作?
XML 通过添加 DTD 和 CDATA 进行修改,以指定数据元素中的内容必须被视为字符数据。
data = io.BytesIO(B'''<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE root [
<!ELEMENT root (data+)>
<!ELEMENT data (#PCDATA)>
]>
<root>
<data>
<![CDATA[
<x>foo<y>bar</y>
]]>
</data>
<data>
<![CDATA[
<z>foo<y>bar</y>
]]>
</data>
</root>
''')
from lxml import etree
# see below why html=True
context = etree.iterparse(data, events=("end",), tag=("data",), dtd_validation=True, load_dtd=True)
contents = [] # I don't keep lists in the "real" application
for event, elem in context:
contents.append(etree.tostring(elem)) # get back the full content underneath data
我正在处理 XML 内容,其中包含的元素可能包含格式不正确的 XML/markup-like(例如 HTML)文本内容。例如:
<root>
<data>
<x>foo<y>bar</y>
</data>
<data>
<z>foo<y>bar</y>
</data>
</root>
目标:我希望lxml.etree
不要尝试将data
元素下的任何内容解析为XML,而只是[=56] =] 它是 bytes
或 str
(可以是 elem.text
)。
文件很大,我想用lxml.etree.iterparse
提取在data
中找到的内容-
元素。
初始想法:获取元素内容(在本例中包含 data
开始和结束标记)的一种直接方法可能是:
data = BytesIO(b"""
<root>
<data>
<x>foo<y>bar</y>
</data>
<data>
<z>foo<y>bar</y>
</data>
</root>
""")
from lxml import etree
# see below why html=True
context = etree.iterparse(data, events=("end",), tag=("data",), html=True)
contents = [] # I don't keep lists in the "real" application
for event, elem in context:
contents.append(etree.tostring(elem)) # get back the full content underneath data
问题 lxml.etree
可以 运行 解析 data
的子项(例如:我已经当 html
数据存储在 data
下时,使用 html=True
不会 运行 出现问题)。我知道 lxml
中有 custom element classes,但根据我对文档的理解,它们不会改变 lxml.etree
由 libxml2
) 规定的解析行为。
有什么简单的方法可以告诉 lxml
不要尝试将元素内容解析为子元素。应用程序本身受益于其他 lxml
功能,如果我单独为 data
编写自定义提取器,我将不得不复制这些功能。
或者是否可以使用 XSLT 首先转换输入以在 lxml
中进行处理,然后再 link 返回数据?
这是否按预期工作? XML 通过添加 DTD 和 CDATA 进行修改,以指定数据元素中的内容必须被视为字符数据。
data = io.BytesIO(B'''<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE root [
<!ELEMENT root (data+)>
<!ELEMENT data (#PCDATA)>
]>
<root>
<data>
<![CDATA[
<x>foo<y>bar</y>
]]>
</data>
<data>
<![CDATA[
<z>foo<y>bar</y>
]]>
</data>
</root>
''')
from lxml import etree
# see below why html=True
context = etree.iterparse(data, events=("end",), tag=("data",), dtd_validation=True, load_dtd=True)
contents = [] # I don't keep lists in the "real" application
for event, elem in context:
contents.append(etree.tostring(elem)) # get back the full content underneath data