我正在尝试查询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);
我希望我的总体思路正确。
编辑:更新的captialization以匹配区分大小写,结果相同。 添加值并将where子句更改为后代括号不起作用。
答案 0 :(得分:2)
正确识别的代码的主要问题是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"));