Linq 使用非标准命名空间查询 XML
本文关键字:查询 XML 命名空间 非标准 Linq | 更新日期: 2023-09-27 18:26:44
我正在尝试查询XML文件,但是某些节点具有命名空间,其他节点则无法获得完整的解决方案。
我想知道是否可以在没有 Xpath 的情况下做到这一点?
.XML
<Household name="Home" xmlns="AP:CB" description="Home" >
<InsuranceClaims/>
<mortgages>
<mortgage id="Sally Mae" xmlns="AP:CB" />
</mortgages>
<Appliances>
<Appliance key="Stove" value="5000" />
</Appliances>
<Persons>
<Person name="Henry" age="35" />
<Person name="Jill" age="23" xmlns="AP:CB"/>
</Persons>
</Household>
所以我们有一个 AP:CB 的命名空间,它存在于某些元素上,而不是其他元素上。
我目前的尝试没有产生任何结果。
_Household = _XDoc.Descendants()
.Where(x => x.Name == "Persons")
.Select(x => new
{
name = (string)x.Element( "Person").Attribute("name").Value,
age = (string)x.Element("Person").Attribute("age").Value
})
.ToDictionary(x => x.age, x => x.name);
我希望我有一个大致的想法。
编辑:更新了大写以匹配区分大小写,结果相同。 添加 Value 并将 where 子句更改为在后代括号中不起作用。
正如您正确识别的那样,代码的主要问题是 XML 命名空间。虽然你错了,代码中的一些元素有它们,有些没有:子节点从其父节点继承xmlns
声明,这意味着文档中的所有元素都位于同一命名空间中。
在具有命名空间的文档上使用 LINQ to XML 时,必须显式指定该命名空间:
XNamespace ns = "AP:CB";
…
_Household = _XDoc.Descendants()
.Where(x => x.Name == ns + "Persons")
.Select(x => new
{
name = (string)x.Element(ns + "Person").Attribute("name").Value,
age = (string)x.Element(ns + "Person").Attribute("age").Value
})
.ToDictionary(x => x.age, x => x.name);
尽管此代码将仅返回单个值(对于 Henry(,因为您选择了所有Persons
元素,并为每个元素选择其第一个Person
子节点。
相反,我会像这样编写查询:
_Household = _XDoc.Descendants(ns + "Persons")
.Elements(ns + "Person")
.ToDictionary(x => (int)x.Attribute("age"), x => (string)x.Attribute("name"));