[英]Navigating project files in XML
我正在寻找解析和修改.dbproj
类型的项目文件。
样本XML
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ProjectGroup></ProjectGroup>
<ItemGroup></ItemGroup>
<ItemGroup></ItemGroup>
<ItemGroup></ItemGroup>
<ItemGroup>
<Build Include="myfile.cs">
<SubType>Code</SubType>
</Build>
<Build Include="myfile2.cs">
<SubType>Code</SubType>
</Build>
<Build Include="myfile3.cs">
<SubType>Code</SubType>
</Build>
</ItemGroup>
<ItemGroup>
<NotInBuild Include="myfile4.cs">
<SubType>Code</SubType>
</NotInBuild>
</ItemGroup>
</Project>
我想从第4个<ItemGroup>
具有Include="myfile.cs"
属性的项目,并将其从所说的<ItemGroup>
删除。 接下来,我要添加此元素:
<NotInBuild Include="myfile.cs">
<SubType>Code</SubType>
</NotInBuild>
从删除到第5个ItemGroup
略有修改。 结果应为:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ProjectGroup></ProjectGroup>
<ItemGroup></ItemGroup>
<ItemGroup></ItemGroup>
<ItemGroup></ItemGroup>
<ItemGroup>
<Build Include="myfile2.cs">
<SubType>Code</SubType>
</Build>
<Build Include="myfile3.cs">
<SubType>Code</SubType>
</Build>
</ItemGroup>
<ItemGroup>
<NotInBuild Include="myfile.cs">
<SubType>Code</SubType>
</NotInBuild>
<NotInBuild Include="myfile4.cs">
<SubType>Code</SubType>
</NotInBuild>
</ItemGroup>
</Project>
在Skeet的另一篇SO帖子中 ,我开始沿着LINQ道路走下去,我不知道从这里去哪里。
XDocument doc = XDocument.Load(XmlDocumentPath);
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
var query = doc.Root
.Elements(ns + "ItemGroup");
使用此收集类和相关的扩展: http : //searisen.com/xmllib/xelementcollection.wiki
这些类:
public class Project
{
XElement self;
public Project(FileInfo file)
{
self = XElement.Load(file.FullName);
}
public ItemGroup[] ItemGroup
{
get
{
return _ItemGroup
?? (_ItemGroup = self.GetEnumerable("ItemGroup", x => new ItemGroup(x)).ToArray());
}
}
ItemGroup[] _ItemGroup;
}
public class ItemGroup
{
XElement self;
public ItemGroup(XElement self)
{
this.self = self;
}
public XElementCollection Build
{
get
{
return _Build
?? (_Build = new XElementCollection(self, "Build",
(a, b) => a.Get("Include", string.Empty) ==
b.Get("Include", string.Empty),
false));
}
}
XElementCollection _Build;
public XElementCollection NotInBuild
{
get
{
return _NotInBuild
?? (_NotInBuild = new XElementCollection(self, "NotInBuild",
(a, b) => a.Get("Include", string.Empty) ==
b.Get("Include", string.Empty),
false));
}
}
XElementCollection _NotInBuild;
}
然后是这种凌乱的实现:
Project project = new Project(xmlFile2);
XElement find = null;
ItemGroup item = project.ItemGroup.FirstOrDefault(i =>
(find = i.Build.Find(x => x.Get("Include", string.Empty) == "myfile.cs")) != null);
if (null != find)
{
XElement not = new XElement(find.Name.Namespace + "NotInBuild");
not.Set("Include", "myfile.cs", true);
foreach (var child in find.Elements().ToArray())
not.Add(child);
find.Remove();
ItemGroup notGroup = project.ItemGroup.FirstOrDefault(i => i.NotInBuild.Count > 0);
notGroup.NotInBuild.Add(not);
}
使用顶部提到的扩展方法,名称空间问题不是问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.