让expat在python中使用.dtd替换实体
我试图读入一个xml文件,如下所示让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é A. Blakeley</author> </incollection> </dblp> 部分:解析器调用其字符处理程
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection>
<author>José 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 "À" >
]>
但这并不能从总体上解决问题。顺便说一句,我可以通过将.dtd的相关部分复制到XML文件本身来暂时帮助自己,如
<!DOCTYPE dblp [
<!ENTITY Agrave "À" >
]>
但这并不能从总体上解决问题。谢谢你的回答。然而,这两种方法都遇到了问题:从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上这样做,但这并不重要,因为它只会影响换行。)哇,非常感谢这些详尽的解释。我会尽快检查并公布我的最终结果。