我想问一下已知的现有Python 2.x库,用于解析内置DTD 的XML文档而不用自动扩展实体。 (有问题的文件:JMdict。)
似乎lxml有一些不解析实体的选项,但最后我试过,实体最终被转换为空白。我只是搜索了这个,并发现pxdom是我可能尝试的另一种选择,但由于它是纯Python,它似乎比我想要的慢得多。
还有其他什么吗?
答案 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节省了我的一天。