Xml DTD校验中关于external entity的实现策略。

在Xml parser的实现中,DTD的实现是一个比较麻烦的地方。麻烦之处不在于DTD的逻辑部分,而在于如何处理DTD的外部Entity,比如,DTD文件间的相互调用。

比如如下的DTD声明:

<!ENTITY imported-file SYSTEM "imported-file">

%imported-file;

上面两段DTD语句,首先声明一个参数化的external Entity, 紧接着引用该external entity,表示导入该DTD文件作为整个DTD的一部分。那么,当Xml Parser遇到这种DTD声明时,该怎么处理呢?

一种方案是,根本不去Parse 该Entity的内容,而是简单的当作一个外部实体,传给应用程序处理。这种方案最为简单,问题是被导入的文件逻辑上是DTD的一个组成部分,其中可能声明了Element,Attlist等,不Parse该文件将导致DTD Validate失败。

第二种方案是,尝试parse该external entity. ok,如果该external entity表示的确实是一个DTD文件,没有问题,但是如果该entity所指向的对象只是一个简单的文本文件,而本身并不是一个有效的DTD文件,那么有可能产生错误。即时可以处理这种Parse错误,也要防止其它的几个问题,比如文件之间的循环引用。最为麻烦的是,有可能用户并不希望将该entity对应的文件作为dtd的一个部分。当xml文件不符合dtd校验,而该文件瞧好包含一个正确的dtd声明时,有可能导致dtd validate的无效性。本应该报错的,现在成了正确的xml文件了。

当然,正确的做法是,每次发现external entity的声明时,发送给用户一个信息,由用户指定特定的动作。这种方案麻烦的时,xml parser使用的时候接口比较麻烦,必须由用户先给Parser指定一个entity动作,然后才能开始Parse.

本人以OpenOffice的xml文件为例,分别使用.Net的xml parser和Xerces c++进行parse,在不指定任何Entity handler的情况下,.Net parser没有问题,而Xerces c++则会报错。出错的地方就是DTD的校验部分。可见这两个Parser在external dtd的处理上有着明显的差异。另外,XmlSpy 2004也能够正常校验。

你可能感兴趣的:(Xml DTD校验中关于external entity的实现策略。)