不知何故,有时以下代码在加载有效的Windows-1252 XML时会产生错误。

使用MSXML6在Windows XP Professional x86 SP3上失败。
它使用MSXML6在Windows 7 Ultimate x64 SP1上成功运行。

注意:以下代码是用Delphi编写的,但是等效代码在其他环境中也会失败。

procedure TXMLEOSErrorTestCase.Test;
var
  XmlDocument: IXMLDOMDocument3;
  XmlFileName: string;
begin
  XmlDocument := CoFreeThreadedDOMDocument60.Create();
  XmlFileName :=  TPath.Combine(TPath.GetDirectoryName(ParamStr(0)), '1-Normal.xml');
  if not XmlDocument.load(XmlFileName) then
    Parse(XmlDocument.parseError);
end;

XmlDocument.load方法期间发生此错误:
reason: System error: -2146697210.
errorCode: -2146697210
url: C:\temp\1-Normal.xml

我将XML缩减为以下XML。

这是XML文件的十六进制转储:
000000: 3C 3F 78 6D 6C 20 76 65  72 73 69 6F 6E 20 3D 20 <?xml version =
000010: 22 31 2E 30 22 20 65 6E  63 6F 64 69 6E 67 3D 22 "1.0" encoding="
000020: 57 69 6E 64 6F 77 73 2D  31 32 35 32 22 3F 3E 3C Windows-1252"?><
000030: 52 4F 57 20 43 69 74 79  3D 22 E0 22 2F 3E 0D 0A ROW City="."/>..

这是XML:
<?xml version = "1.0" encoding="Windows-1252"?><ROW City="à"/>

为什么会发生错误?

(XML可以在.NET和其他不使用MSXML6的环境中完美加载,在Windows 7 Ultimate x64 SP1上也可以正常运行)。

--jeroen

最佳答案

该行为取决于您所安装的MSXML6.DLL的版本。

为了更好地重现此问题,除了问题中的abnormal.xml之外,我还创建了另一个文件normal.xml

文件转储abnormal.xml:

000000: 3C 3F 78 6D 6C 20 76 65  72 73 69 6F 6E 3D 22 31 <?xml version="1
000010: 2E 30 22 20 73 74 61 6E  64 61 6C 6F 6E 65 3D 22 .0" standalone="
000020: 79 65 73 22 3F 3E 3C 52  4F 57 20 43 69 74 79 3D yes"?><ROW City=
000030: 22 E0 22 2F 3E 0D 0A                             "."/>..

文件abnormal.xml:
<?xml version="1.0" standalone="yes"?><ROW City="à"/>

文件转储normal.xml:
000000: 3C 3F 78 6D 6C 20 76 65  72 73 69 6F 6E 20 3D 20 <?xml version =
000010: 22 31 2E 30 22 20 65 6E  63 6F 64 69 6E 67 3D 22 "1.0" encoding="
000020: 57 69 6E 64 6F 77 73 2D  31 32 35 32 22 3F 3E 3C Windows-1252"?><
000030: 52 4F 57 20 43 69 74 79  3D 22 E0 22 2F 3E 0D 0A ROW City="."/>..

文件normal.xml:
<?xml version = "1.0" encoding="Windows-1252"?><ROW City="à"/>

我期望的行为是:
  • abnormal.xml失败,因为它未指定编码,但包含一个具有高位设置的字符
  • normal.xml成功,因为它支持支持高位字符的单字节编码,因此允许设置高位的字符

  • 这些是观察到的方案:

    MSXML6失败:
    reason: System error: -2146697210.
    errorCode: -2146697210
    url: file:///C:/My%20Dropbox/XMLEOSErrorTest/Abnormal.xml
    
    reason: System error: -2146697210.
    errorCode: -2146697210
    url: file:///C:/My%20Dropbox/XMLEOSErrorTest/Normal.xml
    

    MSXML6成功:
    reason: An invalid character was found in text content.
    
    errorCode: -1072896760
    url: file:///C:/My%20Dropbox/XMLEOSErrorTest/Abnormal.xml
    srcText: <?xml version="1.0" standalone="yes"?><ROW City="
    line: 1
    linepos: 50
    filepos: 49
    

    这是什么版本失败的概述。
    括号之间的DLL名称来自其版本信息。
    failure; XP Professional SP3:
    msxml6.dll       version 6.20.1099.0  (MSXML 6.0 SP2)
    msxml6r.dll      version 6.0.3883.0   (XML Resources)
    
    success; Windows 7 Ultimate x64 SP1:
    msxml6.dll       version 6.30.7600.16385  (MSXML 6.0 SP3)
    msxml6r.dll      version 6.30.7600.16385
    msxml6r.dll.mui  version 6.30.7600.16385
    
    success; XP Professional SP3:
    msxml6.dll       version 6.20.1103.0  (MSXML 6.0 SP3)
    msxml6r.dll      version 6.0.3883.0   (XML Resources)
    

    观察结果:
  • Windows Update自动和Microsoft Update不会将MSXML6.DLL更新到Windows XP SP3上的最新版本。
  • 没有适用于Windows XP的MSXML6 SP3。
  • 实际上,最新版本是Windows XP SP2的6.20.2003.0,可以在http://support.microsoft.com/kb/973686上获得(在Windows XP SP3上安装而不是)。
  • 可以从http://support.microsoft.com/kb/973687(direct download for XP SP3)
  • 获得Windows XP SP3的MSXML6.DLL的6.20.1103.0版本。
  • Microsoft在其站点上对此的信息很少:http://www.google.com/search?q=msxml6+%226.20.1099.0%22+%226.20.1103.0%22+site:microsoft.com
  • 仅搜索6.20.1103.0不会显示更多内容:http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=msxml6+%226.20.1103.0%22+site:microsoft.com
  • 这样可以提供最佳搜索结果:http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=msxml6+%226.20.1103.0%22#sclient=psy&num=10&hl=en&q=msxml6+%226.20.1099.0%22+%226.20.1103.0%22

  • 因此:在执行MSXML6时,首先要检查您是否确实具有目标Windows版本的最新MSXML6.DLL。

    --jeroen

    08-18 03:59