如何让IXmlDomDocument2.XML正确地转义引号?

时间:2011-02-03 23:10:23

标签: xml delphi ixmldomdocument

我正在解决一个问题,即从我们的程序导出的XML不会转义引号(将"转换为"),导致接收端出现问题。它可以逃脱& s和尖括号,但不是引号。

当我在XML导出代码中挖掘时,我发现它是一个非常简单的IXmlDomDocument2 DOM接口。但是当我通过调用.XML方法进入生成XML字符串输出的步骤时,我跑进了一条我无法追踪的私有墙,因为所有的工作都发生在{ {1}}。

显然,微软的C:\Windows\System32\msxml3.dll实现知道如何逃避某些符号而不是其他符号。更糟糕的是,显而易见但丑陋的解决方案(通过递归遍历整个文档运行预处理步骤并在调用IXmlDomDocument2之前用'''替换值中的所有引号)将无效,因为.XML方法会在那里看到那些&逃避它们!有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:3)

这可以被认为是另一端使用的XML Parser中的错误。 XML规范详细说明了可以转义的实体。但是它们只需要在属性中进行转义,如下所示:

program Project2;

{$APPTYPE CONSOLE}

uses
  ActiveX,
  MSXML2_TLB,
  SysUtils;
var
  Dom : IXMLDOMDocument2;
  Root :  IXMLDOMNode;
  Attr : IXMLDOMNode;
begin
  CoInitialize(nil);
  try
    DOM := CoDOMDocument40.Create;
    Root := Dom.createElement('root');
    Attr := Dom.createAttribute('attr');
    Attr.text := '"';
    root.attributes.setNamedItem(Attr);
    root.text := '"Hello World"';
    DOM.appendChild(Root);
    writeln(Root.xml);
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

但实际情况是,你可能无法掌控方程式的另一面。 因此,您可以执行以下操作:

program Project2;

{$APPTYPE CONSOLE}

uses
  ActiveX,
  MSXML2_TLB,
  SysUtils;
function QuoteEscape(const v : String) : String;
begin
  result := StringReplace(V,'"','"',[rfReplaceAll]);
end;


var
  Dom : IXMLDOMDocument2;
  Root :  IXMLDOMNode;
  Attr : IXMLDOMNode;
begin
  CoInitialize(nil);
  try
    DOM := CoDOMDocument40.Create;
    Root := Dom.createElement('root');
    Attr := Dom.createAttribute('attr');
    Attr.text := '"';
    root.attributes.setNamedItem(Attr);
    root.text :=  QuoteEscape('"Hello World"');
    DOM.appendChild(Root);
    writeln(StringReplace(Root.xml,'"','"',[rfReplaceAll]));
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.