1

我正在解决一个问题,即从我们的程序导出的 XML 不会转义引号,("变成",)会导致接收端出现问题。它可以很好地转义 &s 和尖括号,但不能转义引号。

当我深入研究 XML 导出代码时,我发现它是一个非常简单的IXmlDomDocument2DOM 接口。但是当我到达通过调用该.XML方法生成 XML 字符串输出的步骤时,我撞到了一堵我无法追踪的专有性墙,因为所有工作都发生在C:\Windows\System32\msxml3.dll.

所以显然微软的IXmlDomDocument2实现知道如何转义一些符号而不是其他符号。更糟糕的是,显而易见但丑陋的解决方案(在我调用之前通过递归遍历整个文档并用 '"' 替换值中的所有引号来运行预处理步骤.XML)将不起作用,因为该.XML方法会看到那些 &s在那里逃脱他们!有什么办法可以解决这个问题吗?

4

1 回答 1

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.
于 2011-02-03T23:55:04.210 回答