让expat在python中使用.dtd替换实体

让expat在python中使用.dtd替换实体,python,xml,entity,dtd,expat-parser,Python,Xml,Entity,Dtd,Expat Parser,我试图读入一个xml文件,如下所示 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE dblp SYSTEM "dblp.dtd"> <dblp> <incollection> <author>Jos&eacute; A. Blakeley</author> </incollection> </dblp> 部分:解析器调用其字符处理程

我试图读入一个xml文件,如下所示

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection>
<author>Jos&eacute; A. Blakeley</author>
</incollection>
</dblp>
部分:解析器调用其字符处理程序两次,一次使用“Jos”,一次使用“A.Blakeley”。 现在我明白了,如果它不知道eacute实体,那么这可能是正确的行为。但是,这是在dblp.dtd中定义的。不过,我似乎无法说服expat使用此文件。我只能说

p = xml.parsers.expat.ParserCreate()
# tried with and without following line
p.SetParamEntityParsing(xml.parsers.expat.XML_PARAM_ENTITY_PARSING_ALWAYS) 
p.UseForeignDTD(True)
f = open(dblp_file, "r")
p.ParseFile(f)
但侨民仍然不承认我的实体。为什么没有办法告诉外籍人士使用哪种DTD?我试过了

  • 将文件放入与XML相同的目录中
  • 将文件放入程序的工作目录
  • 将xml文件中的引用替换为绝对路径

我错过了什么?Thx.

据我所知,如果您直接使用pyexpat,那么您必须提供自己的
ExternalEntityRefHandler
来获取外部DTD并将其提供给expat

参见示例代码,例如
xml.sax.expatreader
(Python 2.6中的方法
external\u entity\u ref
,第374行)


如果可以的话,最好使用更高级的接口,比如SAX(通过
expatreader
)。

据我所知,如果您直接使用pyexpat,那么您必须提供自己的
ExternalEntityRefHandler
来获取外部DTD并将其提供给expat

参见示例代码,例如
xml.sax.expatreader
(Python 2.6中的方法
external\u entity\u ref
,第374行)


如果可以的话,最好使用更高级别的接口,如SAX(通过
expatreader
)。

顺便说一句,我可以将.dtd的相关部分复制到XML文件本身中,如

<!DOCTYPE dblp [
    <!ENTITY Agrave  "&#192;" >
]>


但这并不能从总体上解决问题。

顺便说一句,我可以通过将.dtd的相关部分复制到XML文件本身来暂时帮助自己,如

<!DOCTYPE dblp [
    <!ENTITY Agrave  "&#192;" >
]>


但这并不能从总体上解决问题。

谢谢你的回答。然而,这两种方法都遇到了问题:从external_entity_ref中的示例来看,我仍然不知道如何在这里包含DTD。使用xml.sax.make_解析器,我得到feed self中第207行的文件“…expatreader.py”。_parser.Parse(data,isFinal)。。。UnicodeEncodeError:“ascii”编解码器无法对位置0处的字符u'\xe9'进行编码:序号不在范围内(128)。这两个问题显然与我缺乏包含这些库的内部工作原理的知识有关,但是我有点困惑,这样一个琐碎的任务需要这么多的知识,
external\u entity\u ref
方法在
sysid
中接收外部实体的地址(这里是DTD,
dblp.DTD
)。它从该源获取数据(
prepare\u input\u source
),创建新的解析上下文(
ExternalEntityParserCreate
),并回调到解析循环以继续,从外部源而不是原始源获取内容。要使DTD在您自己的pyexpat代码中工作,您必须重现这种丑陋的过程?由于某种原因,它看起来是被输入unicode字符,而不是XML解析器应该输入的字节。XML有自己的内置字节到字符解码机制,所以您不希望Python为您这样做。您没有使用Python 3,是吗?如果是这样,您应该确保使用
rb
而不是
r
以字节形式打开文件。(实际上,你也应该在Python2上这样做,但这并不重要,因为它只会影响换行。)哇,非常感谢这些详尽的解释。我会尽快检查并公布我的最终结果。谢谢你的回答。然而,这两种方法都遇到了问题:从external_entity_ref中的示例来看,我仍然不知道如何在这里包含DTD。使用xml.sax.make_解析器,我得到feed self中第207行的文件“…expatreader.py”。_parser.Parse(data,isFinal)。。。UnicodeEncodeError:“ascii”编解码器无法对位置0处的字符u'\xe9'进行编码:序号不在范围内(128)。这两个问题显然与我缺乏包含这些库的内部工作原理的知识有关,但是我有点困惑,这样一个琐碎的任务需要这么多的知识,
external\u entity\u ref
方法在
sysid
中接收外部实体的地址(这里是DTD,
dblp.DTD
)。它从该源获取数据(
prepare\u input\u source
),创建新的解析上下文(
ExternalEntityParserCreate
),并回调到解析循环以继续,从外部源而不是原始源获取内容。要使DTD在您自己的pyexpat代码中工作,您必须重现这种丑陋的过程?由于某种原因,它看起来是被输入unicode字符,而不是XML解析器应该输入的字节。XML有自己的内置字节到字符解码机制,所以您不希望Python为您这样做。您没有使用Python 3,是吗?如果是这样,您应该确保使用
rb
而不是
r
以字节形式打开文件。(实际上,你也应该在Python2上这样做,但这并不重要,因为它只会影响换行。)哇,非常感谢这些详尽的解释。我会尽快检查并公布我的最终结果。