【问题标题】:How to reformat XML programmatically?如何以编程方式重新格式化 XML?
【发布时间】:2011-05-17 08:33:18
【问题描述】:

我在输入上有一个 XML 文档,它的格式非常糟糕(如果有人关心的话,它是 Delphi 项目文件)——不一致的缩进、空行、节点字符串集中在一起:

<BorlandProject><Delphi.Personality><Parameters><Parameters Name="HostApplication">C:\Some\Path\Filename.exe</Parameters> <!--etc--> <Excluded_Packages>


</Excluded_Packages>

我想把它重新格式化成漂亮的东西。使用 Win32/COM 以编程方式执行此操作的最简单方法是什么?如果是 MSXML,我该怎么办?

我也希望能够指定缩进单位(制表符/几个空格)。

我尝试使用 Delphi 的 MSXML 包装器 TXmlDocument,它确实删除了带有制表符的空行和缩进节点,但它不会像这样拆分行:

<BorlandProject><Delphi.Personality><Parameters><Parameters Name="HostApplication">C:\Some\Path\Filename.exe</Parameters> <!--etc--> <Excluded_Packages>

【问题讨论】:

  • 似乎是一个命令行工具,但我是 XML/XSLT 的新手,所以如果我有什么误解,请详细说明。

标签: xml delphi msxml


【解决方案1】:

我使用Tidy 来格式化 XML。 RRUZ 使用 xmlDoc.FormatXMLData 的方法效果很好,用起来也很有意义,但是如果你的 XML 文件比较大,那它可能就不太好用了。当我尝试格式化一个 100 MB 的单行 XML 文件时,应用程序在 4GB 机器上因内存不足错误而崩溃,而且速度也很慢。

我使用的是命令行版本的 tidy。还有一个 DLL 版本,还有一个 Delphi 头文件,你可以找到它,但我发现通过 CreateProcess 运行 exe 比学习 DLL API 更方便。

这是我使用的命令行:

tidy.exe -xml -wrap 0 -indent -quiet -o outFile.xml inFile.xml

tidy.exe 是独立的,您不需要 DLL 或其他任何东西。

格式化 XML 的其他可能性是 xmllint 和 xml starlet。

我根本无法让 xmllint 运行,但如果我坚持下去,我相信我可以做到。

xml starlet 似乎运行良好,但它没有任何选项可以写入文件,只能写入标准输出,所以我没有使用它,因为我必须弄清楚如何捕获输出。

【讨论】:

  • 捕获 stdout 输出就像在命令末尾添加以下内容一样简单 ">outfile.xml"
【解决方案2】:

我在一个 delphi 项目文件中测试了FormatXMLData 函数并且工作正常,所有行都正确缩进。

检查此代码。

uses
 XMLIntf,
 XMLDoc;

Procedure FormatXMLFile(const XmlFile:string);
var
   oXml : IXMLDocument;
 begin
   oXml := TXMLDocument.Create(nil);
   oXml.LoadFromFile(XmlFile);
   oXml.XML.Text:=xmlDoc.FormatXMLData(oXml.XML.Text);
   oXml.Active := true;
   oXml.SaveToFile(XmlFile);
 end;

【讨论】:

  • iirc 在某些版本(包括 Delphi 2007)中使用 TXMLDocument 变量导致内存泄漏......我还没有在 Delphi 2009 中对其进行测试,但从那时起我只使用 IXMLDocument 类型变量。也许这就是在此代码示例中将引用设置为 nil 而不是使用 Free 的原因?
  • RRUZ,不应该将 oXml 定义为 IXMLDocument,因为您依赖引用计数来释放它?还需要将 XMLIntf 添加到 uses 子句中。
  • 在这种情况下您是否有任何理由使用 IXMLDocument(只是读取、重新格式化和写入)? IXMLDocument 的开销太大了。 FormatXMLData方法接受一个字符串,输出一个字符串,两者都有读写方式,开销较小。
  • Chris J,我使用IXMLDocument 来避免xml文件的编码问题。
猜你喜欢
  • 2015-04-20
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 2011-10-06
相关资源
最近更新 更多