Skip to main content
 首页 » 编程设计

python之使用没有根/父元素的 lxml.etree

2025年05月04日8cyq1162

我有一些看起来像这样的 SGML

<!DOCTYPE sometype> 
<ITEM> 
<DATE>19-OCT-1987</DATE> 
<TEXT> 
<TITLE>I AM THE TITLE</TITLE> 
<AUTHOR>I AM THE AUTHOR</AUTHOR> 
<DATELINE>WHEN I WAS CREATED</DATELINE><BODY> 
I WANT TO PRESERVE THIS TAG! 
</BODY></TEXT> 
</ITEM> 
<ITEM>... 

我试图用 lxml.html 解析它,但它似乎去除了我需要保留的 BODY 标签。接下来我尝试使用 lxml.etree,但正如您所见,所有 ITEM 标签都没有共同的父元素。我目前使用的代码

doc = """<!DOCTYPE sometype> 
<ITEM> 
<DATE>19-OCT-1987</DATE> 
<TEXT> 
<TITLE>I AM THE TITLE</TITLE> 
<AUTHOR>I AM THE AUTHOR</AUTHOR> 
<DATELINE>WHEN I WAS CREATED</DATELINE><BODY> 
I WANT TO PRESERVE THIS TAG! 
</BODY></TEXT> 
</ITEM>""" 
 
from lxml import etree 
parser = etree.XMLParser(recover=True) # I have invalid HTML chars to ignore 
sgml = etree.fromstring(doc, parser) 

现在 sgml 只是第一个 ITEM 元素。我需要它是所有 ITEM 元素。有任何想法吗? lxml.html 做我想做的事,但默认情况下它会去除 BODY 标签,而且我还没有找到禁用此行为的方法。

请您参考如下方法:

没有共同的父元素?就做一个吧! 您可以重写它们以具有父元素,比如 ROOT。插入 <ROOT>在第一个之前 <ITEM>和 </ROOT>在文档的末尾。以编程方式进行操作非常简单,即使您必须保留实际的磁盘内容。

例如。

<!DOCTYPE sometype> 
<ROOT> 
<ITEM> 
<DATE>19-OCT-1987</DATE> 
<TEXT> 
<TITLE>I AM THE TITLE</TITLE> 
<AUTHOR>I AM THE AUTHOR</AUTHOR> 
<DATELINE>WHEN I WAS CREATED</DATELINE><BODY> 
I WANT TO PRESERVE THIS TAG! 
</BODY></TEXT> 
</ITEM> 
<ITEM> 
<DATE>19-OCT-1879</DATE> 
<TEXT> 
<TITLE>I AM THE TITLE</TITLE> 
<AUTHOR>I AM THE AUTHOR</AUTHOR> 
<DATELINE>WHEN I WAS CREATED</DATELINE><BODY> 
I WANT TO PRESERVE THIS TAG! 
</BODY></TEXT> 
</ITEM> 
<ITEM> 
<DATE>19-OCT-9871</DATE> 
<TEXT> 
<TITLE>I AM THE TITLE</TITLE> 
<AUTHOR>I AM THE AUTHOR</AUTHOR> 
<DATELINE>WHEN I WAS CREATED</DATELINE><BODY> 
I WANT TO PRESERVE THIS TAG! 
</BODY></TEXT> 
</ITEM> 
</ROOT> 

我刚刚试过了,它似乎可以满足您的要求。另存为/tmp/goodfoo 并加载 lxml.etree.fromstring(allcontent) ;然后我像这样访问了你说“想要保留”的文本:b.getchildren()[0].getchildren()[-1].getchildren()[-1].text

(即获取第一个ITEM,获取其TEXT元素,获取TEXT元素的BODY元素,返回BODY元素的任意文本内容。)