当我尝试使用DTD读取XML文档(eagle文件)时,我收到错误:
Project xx引发异常类EDOMParserError,消息'DTD is 禁止“
XML标头如下所示:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
如果我删除第二行......
<!DOCTYPE eagle SYSTEM "eagle.dtd">
......一切正常。
在一些谷歌搜索之后,似乎默认情况下MSXML解析器有一个名为'prohibitDTD'的选项设置为 true (在早期版本中它是假的)。
但是,似乎无法从TXMLDocument类将此选项设置为false。一个解决方案似乎是重新编译.pas库或使用CoCreateInstance()创建我自己的接口。
我在Delphi中看到的所有例子都让我很难将这些示例转换为C ++ Builder。
有谁知道如何使用C ++ Builder XE2读取DTD XML文档?
我的示例代码......
#include <xmldoc.hpp>
_di_IXMLNode XMLObject;
TXMLDocument *XMLDocument = new TXMLDocument(this);
XMLDocument->LoadFromFile(fileName); // <----- Exception EDOMParserError
XMLObject = XMLDocument->DocumentElement;
谢谢...
答案 0 :(得分:5)
XE2为这个问题引入了一个原生解决方案:在bool
中声明了一个名为MSXML6_ProhibitDTD
的全局Xml.Win.msxmldom.hpp
变量。在将数据加载到false
之前,您可以将其设置为TXMLDocument
:
#include <xmldoc.hpp>
#include <msxmldom.hpp>
MSXML6_ProhibitDTD = false;
TXMLDocument *XMLDocument = new TXMLDocument(this):
XMLDocument->LoadFromFile(fileName);
_di_IXMLNode XMLObject = XMLDocument->DocumentElement;
侧面说明:像这样动态创建TXMLDocument
个实例通常不是一个好主意。最好使用IXMLDocument
界面:
#include <xmldoc.hpp>
#include <msxmldom.hpp>
MSXML6_ProhibitDTD = false;
_di_IXMLDocument XMLDocument = LoadXMLDocument(fileName);
_di_IXMLNode XMLObject = XMLDocument->DocumentElement;
答案 1 :(得分:1)
由于全局变量top: Unknown instance:
的变通方法已被弃用,我也无法使用XE5,这是另一种解决方案:
如documentation中所述,有一种方法可以更改DOM属性
MSXML6_ProhibitDTD
不幸的是,使用它并不是那么简单......
包含此命名空间的标题:
Xml.Win.Msxmldom.MSXMLDOMDocumentFactory.AddDOMProperty
并访问此方法。 (强制转换是必要的,因为#include <Xml.Win.msxmldom.hpp>
Foo::Foo()
{
//change the dom property in your constructor.
((TMSXMLDOMDocumentFactory*)Xml::Win::Msxmldom::MSXMLDOMDocumentFactory)->AddDOMProperty("ProhibitDTD", False, true);
}
本身是从元类接口继承的。我没有后面的概念。)
受到delphi博客的启发:https://bobsotherblog.wordpress.com/2013/09/19/fixing-dtd-is-prohibited-error-in-delphi/
答案 2 :(得分:0)
您需要将MSXMLDOM.pas复制到项目文件夹中,然后对其进行修改以解决此问题。
将function TMSDOMDocument.GetMSDocument
的实施更改为以下内容,然后重建项目。
请注意,您必须使用IXMLDOMDocument2.setProperty
而不是直接访问ProhibitDTD
,因为IXMLDOMDocument2
不会发布ProhibitDTD
。
function TMSDOMDocument.GetMSDocument: IXMLDOMDocument;
var
Doc2: IXMLDOMDocument2;
begin
Result := MSNode as IXMLDOMDocument;
if Supports(Result, IXMLDOMDocument2, Doc2) then
Doc2.setProperty('ProhibitDTD', False);
end;
请注意,只有当您 使用运行时包构建时,这才有效!
此解决方案来自TeamB成员的Embarcadero论坛帖子;我记得读过它,发现它是通过CodeNewsFast搜索这些论坛 - 在EMBT论坛上的搜索功能一直运作良好,最近的重建或重新索引或其他东西使它甚至比之前。 : - )