Joe*_*oel 16 c# xml linq-to-xml
我尝试从visual studio*.csproj文件中查询元素.我创建了一个简短的例子来说明问题:
// Working
string xml1 = @"<Project ToolsVersion='4.0'>
<ItemGroup Label='Usings'>
<Reference Include='System' />
<Reference Include='System.Xml' />
</ItemGroup>
</Project>";
// Not working
string xml2 = @"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
<ItemGroup Label='Usings'>
<Reference Include='System' />
<Reference Include='System.Xml' />
</ItemGroup>
</Project>";
XDocument doc = XDocument.Parse(xml2);
foreach (XElement element in doc.Descendants("ItemGroup"))
{
Console.WriteLine(element);
}
Run Code Online (Sandbox Code Playgroud)
字符串xml1工作正常,xml2不返回任何内容.这些字符串之间的唯一区别是文档根目录中的xmlns属性.
我如何查询包含xmlns属性的文档?当xml文档包含xmlns属性时,为什么会出现问题?
Jon*_*eet 19
当xml文档包含xmlns属性时,为什么会出现问题?
它不是,如果你理解它的含义:)基本上你已经将" http://schemas.microsoft.com/developer/msbuild/2003 " 的默认命名空间URI 应用于所有元素.因此,在查询时,您还需要指定该命名空间.幸运的是,LINQ to XML使这非常简单:
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
XDocument doc = XDocument.Parse(xml2);
foreach (XElement element in doc.Descendants(ns + "ItemGroup"))
{
Console.WriteLine(element);
}
Run Code Online (Sandbox Code Playgroud)
不必事先知道名称空间。您可以编写适用于两个Xml的代码,因为您可以从XElement获取默认名称空间。
XDocument doc = XDocument.Parse(xml2);
XNamespace ns = doc.Root.GetDefaultNamespace();
foreach (XElement element in doc.Descendants(ns + "ItemGroup"))
{
Console.WriteLine(element);
}
Run Code Online (Sandbox Code Playgroud)
我还写了一个扩展方法来解析任何XObject(XElement,XDocument等)中的XName。
使用扩展方法而不是GetDefaultNamespace的好处是您不必检查是否已经提供了另一个Namespace。
public static XName ResolveName(this XObject xObj, XName name)
{
//If no namespace has been added, use default namespace anyway
if (string.IsNullOrEmpty(name.NamespaceName))
{
name = xObj.Document.Root.GetDefaultNamespace() + name.LocalName;
}
return name;
}
Run Code Online (Sandbox Code Playgroud)
你可以这样使用
XDocument doc = XDocument.Parse(xml2);
foreach (XElement element in doc.Descendants(doc.ResolveName("ItemGroup")))
{
Console.WriteLine(element);
}
Run Code Online (Sandbox Code Playgroud)
我认为LINQ to XML是一个很棒的API。但是我认为很清楚,如果我不提供名称空间,那我总是指默认名称空间。我看不出LINQ to XML不能以这种方式运行的任何原因。这是一个让我非常恼火的缺点。第一次作为LINQ to XML的初学者,当我忘记提供默认名称空间时,我几个小时都不知道自己做错了什么。