Python:在保留实体的同时解析XML文档

时间:2010-08-17 12:37:47

标签: python xml parsing entity

我想问一下已知的现有Python 2.x库,用于解析内置DTD 的XML文档而不用自动扩展实体。 (有问题的文件:JMdict。)

似乎lxml有一些不解析实体的选项,但最后我试过,实体最终被转换为空白。我只是搜索了这个,并发现pxdom是我可能尝试的另一种选择,但由于它是纯Python,它似乎比我想要的慢得多。

还有其他什么吗?

4 个答案:

答案 0 :(得分:3)

问题中提到了

lxml,就我所知,它可以做你想做的事情。测试代码:

   
from lxml import etree

XML = """
<!DOCTYPE root [
<!ENTITY abc "123">
]>
<root>
&abc;
</root>"""

parser = etree.XMLParser(resolve_entities=False)

root = etree.fromstring(XML, parser)
print "Entity not resolved:"
print etree.tostring(root)
print

print "Entity resolved:"
root = etree.fromstring(XML)
print etree.tostring(root)

输出:

Entity not resolved:
<root>
&abc;
</root>

Entity resolved:
<root>
123
</root>

答案 1 :(得分:1)

似乎用例相当异常;不扩展实体似乎违背了解析器通常根据XML规范工作的方式。

所以,我认为最简单的方法就是克服这个问题。我通过re.finditer手动提取标签,并制作了映射字典。从这里开始,只需扫描解析后的输出并为我的应用做正确的事情。对我的用例我认为足够好了。

答案 2 :(得分:1)

例如,BeautifulSoup中的BeautifulStoneSoup默认情况下不会展开实体。

对于您的用例,可能不会快速或有效,因为它适用于不同类型的用法(处理各种不正确和损坏的标记)。

答案 3 :(得分:0)

我遇到了类似的问题需要解决。我需要读取包含

等实体的TEI XML文件
&some_exotic_char;

在单独的DTD文件中声明。任务是在某些标签中添加一些属性并编写修改后的文件,同时保留特殊实体,而不是弄乱XML布局。

BeautifulSoup工作得很好,直到我想再次写出XML文件:

with open('outfile.xml','w') as outfile:
    outfile.write(soup.prettify())

然后将实体“保持原样”,而是将它们扩展为utf8字符,这不是我想要的。另外,无论美化方法如何,它都会破坏原始的XML布局(没有它,甚至更糟)。

最后我放弃了,最后使用 Perl XML :: LibXML 找到了一个很好的解决方案。用方法

$parser->expand_entities(0);

实体不会扩展。将XML写回文件将保持原始布局的完整。

use XML::LibXML;
my $parser = new XML::LibXML;
$parser->validation(0);
$parser->load_ext_dtd(1);
$parser->expand_entities(0);
my $doc  = $parser->parse_file('infile.xml');

... # do whatever you need to do

open my $out, '>', 'outfile.xml';
binmode $out;
print $out $doc->toString();
close $out;

Perl的XML :: LibXML节省了我的一天。