在previous question中我提到了一些第三方DLL的工作,它的接口使用一系列使用DTD定义的XML输入。到目前为止,一切都进展顺利,但在生成的输入值中解析文档类型声明时仍然存在这个棘手的问题。
我无法弄清楚决定在哪里查找引用的DTD文件的决定因素。如果我的声明如下:
<!DOCTYPE ElementName SYSTEM "ElementName.dtd">
我最初的想法是应用程序的当前执行路径是解析器查找DTD的位置。但是,当我尝试在ASP.Net中使用XML control时,错误让我感到困惑......
无法找到文件'c:\ Program Files \ Microsoft Visual 工作室 9.0 \ Common7 \ IDE \ ElementName.dtd'
为什么要在那里寻找DTD?
是否有任何XML专家可以帮助我解决这个问题。我真的无法控制从这个DLL返回的XML,所以我该怎么做。有没有办法在操作系统中“注册”DTD?像GAC一样?
答案 0 :(得分:3)
不幸的是,生成XML的库使用了dtd的相对url而不是完全限定的url。因此,XmlControl的XmlDocument使用XmlResolver类将相对路径转换为完全限定的路径。默认情况下,它使用XmlUrlResolver(具体的XmlResolver)。这将尝试将dtd的位置映射到它认为相对于Xml文档的位置。麻烦的是,XmlDocument在哪里?可能在内存中与任何东西都不相关,而XmlUrlResolver正在使用进程位置,而在你的情况下是Visual Studio,它位于'c:\ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ devenv.exe'。
那你能做什么?好吧,我想你必须为自己创建一个继承自XmlUrlResolver的XmlResolver,并覆盖ResolveUri方法并做一些合适的事情。完成后你必须:
坦率地说,这有点痛苦,所以如果我在哪里,我会使用string.Replace从文档中删除DTD声明,然后再将其处理成XML。
如果你真的很勇敢,你可以创建一个直接从XmlResolver继承的解析器。完成后,您可以覆盖GetEntity方法,然后您可以从任何地方获取dtd文档。我写过一次从嵌入资源文件的文件中获取dtds,但不幸的是,我没有代码了: - (
答案 1 :(得分:0)
如果您实际上并不关心根据其DTD验证每个文档,可以在XmlTextReader(或XmlDocument)上将XmlResolver属性设置为null以完全忽略DTD。