如何防止TXMLDocument处理PAD文件时删除 实体?
解决TXMLDocument(MSXML)保存XML时丢失
实体的问题
MSXML在解析XML时会将 实体解析为ASCII回车符(#13),默认保存时会规范化换行字符,导致回车符被移除或转换,最终丢失 实体。可以通过以下两种方法解决:
方法一:开启空白保留属性
通过设置TXMLDocument的空白保留选项,并强制底层MSXML DOM文档保留空白字符,阻止其规范化回车符:
procedure ProcessFile1(const SrcFileName: string); var XmlFile: IXMLDocument; DOMDoc: IXMLDOMDocument; begin XmlFile := TXMLDocument.Create(nil); try // 开启TXMLDocument的空白保留选项 XmlFile.Options := XmlFile.Options + [doPreserveWhiteSpace]; XmlFile.LoadFromFile(SrcFileName); // 获取底层MSXML DOM接口,强制设置preserveWhiteSpace为True if Supports(XmlFile.DOMDocument, IXMLDOMDocument, DOMDoc) then begin DOMDoc.preserveWhiteSpace := True; end; XmlFile.SaveToFile(SrcFileName); finally XmlFile := nil; end; end;
方法二:手动转义回车符
如果方法一无效,可以遍历所有文本节点,将解析后的回车符(#13)重新替换为 实体:
procedure EscapeCRInTextNodes(Node: IXMLNode); var I: Integer; TextNode: IXMLTextNode; begin if Node.NodeType = ntText then begin TextNode := Node as IXMLTextNode; // 将回车符替换为 实体 TextNode.Text := StringReplace(TextNode.Text, #13, ' ', [rfReplaceAll]); end; // 递归处理所有子节点 for I := 0 to Node.ChildNodes.Count - 1 do begin EscapeCRInTextNodes(Node.ChildNodes[I]); end; end; procedure ProcessFile1(const SrcFileName: string); var XmlFile: IXMLDocument; begin XmlFile := TXMLDocument.Create(nil); try XmlFile.LoadFromFile(SrcFileName); // 遍历文档所有节点,转义回车符 EscapeCRInTextNodes(XmlFile.DocumentElement); XmlFile.SaveToFile(SrcFileName); finally XmlFile := nil; end; end;
注意事项
- 方法一优先推荐,它利用MSXML原生属性保留原始字符,避免手动处理可能带来的问题。
- 如果原始XML中目标元素带有
xml:space="preserve"属性,MSXML会自动保留空白字符,无需额外设置。
内容的提问来源于stack exchange,提问作者alancc
相关产品推荐
相关产品推荐

