【发布时间】:2016-06-27 06:54:08
【问题描述】:
在一个简单的 .vbproj 文件中:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
...
</PropertyGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>
我想存储<PropertyGroup> 元素的集合。我发现的问题是每次调用 XDocument.Element() 或 XDocument.Elements() 函数时都需要指定(长)命名空间:
string text = File.ReadAllText("My project.vbproj");
XDocument doc = XDocument.Parse(text, LoadOptions.None);
IEnumerable<XElement> propGroups =
doc.Element("{http://schemas.microsoft.com/developer/msbuild/2003}Project").
Elements("{http://schemas.microsoft.com/developer/msbuild/2003}PropertyGroup");
我很确定应该存在一种更友好的语法来简化上面的代码,也许只调用一次 XDocument.Elements() 而不是 XDocument.Element(),或者也许为了避免使用适当的 XPath 指定命名空间(或 mroe 不止一次)并使用 XDocument.XPathSelectElements() 代替,但是,似乎我不能使用 XPATH v2.0 来忽略 //*:Project/PropertyGroup 之类的命名空间(或也许我的语法错了?)。
谁能解释我如何重构它?
请注意,目的是修改 Xml 的某些属性,然后将更改保存在文件中,而不仅仅是获取 Xml 中的数据(如果这对解决方案很重要)。
【问题讨论】:
-
你看过XNamespace吗?
-
@Tim 感谢您的参考,从我看到的 MSDN 代码示例中显示的解决方案与我所做的相同,但只是使用 var 来引用命名空间名称。老实说,我期望其他类型的解决方案比 MSDN 显示的更合适。因为本质上它显示了相同的名称空间字符串,需要一直指定/连接。
-
XName 怎么样?它具有本地名称(没有命名空间)的属性,以及相关 XNamespace 的命名空间和 URI。
-
我通常使用这个:IEnumerable
propGroups = doc.Descendants().Where(x => x.Name.LocalName == "PropertyGroup");