在C#上解析Delphi项目文件

时间:2009-12-06 17:06:09

标签: c# xml delphi

这似乎是一个奇怪的问题,但我有自己的理由!我正在尝试解析Delphi 2009项目文件(.dproj),它是项目的XML表示。我可以将文档加载到XmlDocument中,但是当我尝试访问项目中使用的单元时,SelectNodes会给我一个空列表。

该项目的一个例子如下:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
...
<ItemGroup>
  <DelphiCompile Include="Package.dpk">
    <MainSource>MainSource</MainSource>
  </DelphiCompile>
  <DCCReference Include="vcl.dcp"/>
  <DCCReference Include="Unit1.pas"/>
  <DCCReference Include="Unit2.pas"/>
  <DCCReference Include="Unit3.pas"/>
  <DCCReference Include="Unit4.pas"/>
  <DCCReference Include="Unit5.pas"/>
  ...
</ItemGroup>
</Project>

代码示例如下:

  ProjectDocument.Load(FileName);
  XmlNodeList nodeList;
  XmlElement RootNode = ProjectDocument.DocumentElement;

  string xmlns = RootNode.Attributes["xmlns"].Value;

  // This gives an empty list
  nodeList = RootNode.SelectNodes("/Project/ItemGroup/DCCReference");
  foreach (XmlNode title in nodeList)
  {
    Console.WriteLine(title.InnerXml);
  }

  // This also gives an empty list
  nodeList = RootNode.SelectNodes("/ItemGroup/DCCReference");
  foreach (XmlNode title in nodeList)
  {
    Console.WriteLine(title.InnerXml);
  }

问题是,我做错了什么,因为我必须遗漏一些东西。唯一奇怪的是文档不是.xml,它是.dproj。

所以,如果你能解决这个问题,请提前谢谢。

标记

3 个答案:

答案 0 :(得分:3)

引用the documentation

  

<强>说明

     

如果XPath表达式需要命名空间解析,则必须使用 SelectNodes 重载,该重载以XmlNamespaceManager为参数。 XmlNamespaceManager 用于解析名称空间。

     
    

注意如果XPath表达式不包含前缀,则假定名称空间URI是空名称空间。如果您的XML包含默认命名空间,您仍然必须使用 XmlNamespaceManager 并为其添加前缀和命名空间URI;否则,您将无法选择任何节点。

  

您需要two-argument version of SelectNodes。另请注意,您选择的节点没有内容,因此InnerXML属性将为空。一旦获得非空列表,您的代码仍将打印一个空行列表。

答案 1 :(得分:2)

您需要使用XmlNamespaceManager

var nsmgr = new XmlNamespaceManager(ProjectDocument.NameTable);
nsmgr.AddNamespace("x", ProjectDocument.DocumentElement.NamespaceURI);
var nodes = doc.SelectNodes("descendant::x:DCCReference", nsmgr);

答案 2 :(得分:0)

另外,为什么不使用自己的简单解析器解析DPR文件?找到用途 line,然后抓住每一行,删除注释和最后一个逗号,直到你用分号打一行。

好处#2除了更简单的解析之外,这适用于每个delphi版本,而DPROJ和等效文件与delphi版本到版本的着名不同。