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

Python:在保留实体的同时解析XML文档,python,xml,parsing,entity,Python,Xml,Parsing,Entity,我想问一下,现有的Python2.x库中有哪些用于使用内置DTD解析XML文档而不自动扩展实体的库。(对于好奇的人,有问题的文件:) lxml似乎有一些不解析实体的选项,但我上次尝试时,实体最终被转换为空白。我只是在谷歌上搜索了一下,发现pxdom是我可以尝试的另一种选择,但因为它是纯Python,所以它似乎比我想要的慢得多 还有什么其他的吗?用例似乎很不正常;不扩展实体似乎与解析器通常根据XML规范工作的方式背道而驰 所以,我认为这可能是最容易的胡乱猜测。我已经通过re.finditer手动提

我想问一下,现有的Python2.x库中有哪些用于使用内置DTD解析XML文档而不自动扩展实体的库。(对于好奇的人,有问题的文件:)

lxml似乎有一些不解析实体的选项,但我上次尝试时,实体最终被转换为空白。我只是在谷歌上搜索了一下,发现pxdom是我可以尝试的另一种选择,但因为它是纯Python,所以它似乎比我想要的慢得多


还有什么其他的吗?

用例似乎很不正常;不扩展实体似乎与解析器通常根据XML规范工作的方式背道而驰


所以,我认为这可能是最容易的胡乱猜测。我已经通过re.finditer手动提取了标记,并制作了映射字典。从这里开始,只需扫描解析的输出并为我的应用程序做正确的事情。我认为对于我的用例来说已经足够好了。

例如,
BeautifulStoneSoup
from默认情况下不会扩展实体

不过,对于您的用例来说,它可能不会很快或有效,因为它面向不同的用途(处理各种格式错误和不完整的标记)

是问题中提到的,据我所知,它能满足您的需求。测试代码:

从lxml导入etree
XML=”“”
&abc;
"""
parser=etree.XMLParser(resolve\u entities=False)
root=etree.fromstring(XML,解析器)
打印“未解析的实体:”
打印etree.tostring(根目录)
打印
打印“实体已解析:”
root=etree.fromstring(XML)
打印etree.tostring(根目录)
输出:

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

Entity resolved:
<root>
123
</root>
未解析的实体:
&abc;
实体决议:
123

我有一个类似的问题要解决。我需要读取包含以下实体的TEI XML文件

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

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

with open('outfile.xml','w') as outfile:
    outfile.write(soup.prettify())
然后它将不会保留实体«原样»,而是将它们扩展为utf8字符,这不是我想要的。此外,不管使用何种美化方法,它都会弄乱原始XML布局(没有它,情况更糟)

最后我放弃了,并最终使用PerlXML::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拯救了我的一天。

我认为expat中的
XML.parsers.expat.XML\u PARAM\u ENTITY\u PARSING\u决不会这样做,但它没有任何效果。我想知道它有什么好处。我真的很想让它与expat一起工作,以避免另一种依赖&重写我当前的代码。但这确实解决了问题。