我正在解决一个问题,即从我们的程序导出的XML不会转义引号(将"
转换为"
),导致接收端出现问题。它可以逃脱& s和尖括号,但不是引号。
当我在XML导出代码中挖掘时,我发现它是一个非常简单的IXmlDomDocument2
DOM接口。但是当我通过调用.XML
方法进入生成XML字符串输出的步骤时,我跑进了一条我无法追踪的私有墙,因为所有的工作都发生在{ {1}}。
显然,微软的C:\Windows\System32\msxml3.dll
实现知道如何逃避某些符号而不是其他符号。更糟糕的是,显而易见但丑陋的解决方案(通过递归遍历整个文档运行预处理步骤并在调用IXmlDomDocument2
之前用'''替换值中的所有引号)将无效,因为.XML
方法会在那里看到那些&逃避它们!有没有办法解决这个问题?
答案 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.