使用没有root / parent元素的lxml.etree

时间:2013-05-16 20:48:06

标签: python lxml

我有一些看起来像这样的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标记,但我还没有找到一种方法来禁用此行为。

1 个答案:

答案 0 :(得分:1)

没有共同的父元素?做一个! 您可以将它们重写为具有父元素,例如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元素的任何文本内容。)