按属性值查找XElement

8

我有一个IEnumerable集合,每个集合都有不同的属性值,这些值对应于我的业务对象上的不同属性。以下是我正在查询的XML示例:

  <SimpleData name="zip">60004</SimpleData>
  <SimpleData name="name">ARLINGTON HEIGHTS</SimpleData>
  <SimpleData name="state">IL</SimpleData>
  <SimpleData name="countyname">COOK</SimpleData>
  <SimpleData name="lat">42.1121336684356</SimpleData>
  <SimpleData name="lon">-87.9736682731814</SimpleData> 

我认为我的linq2xml lambda表达式已经接近正确(在搜索MSDN和SO之后),但我似乎无法完全调整好它:

string cityName = simpleData.Where(a => a.Attribute("name").Value == "name").Select(a => a.Value).ToString();

cityName的值被分配给"System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String]",而不是ARLINGTON HEIGHTS。

有什么建议吗?谢谢。

2个回答

16
string cityName = (simpleData.Where(a => a.Attribute("name").Value == "name")
                  .Select(a => a.Value)).FirstOrDefault();

或者

(from x in simpleData
where x.Attribute("name").Value == "name"
select x.Value).FirstOrDefault()

返回一个 IEnumerable<string>,其中包含所有元素值,这些元素的 name 属性等于 name(Linq 扩展方法几乎总是返回集合,而不是单个实例)。 然后我们取第一个元素,如果为空则取 null

此外,那个 XML 真是太可怕了,应该把它弄掉。


5
我建议使用(string)Attribute("name"),而不是Attribute("name").Value——两者几乎相同,但前者会先进行空值检查。由于当一个元素上不存在指定名称的属性时,Attribute()方法将返回null,所以当前写法中第一个找不到属性的元素将引发NullReferenceException异常。 - Pavel Minaev
该死,我知道只是缺了一点小东西,加上FirstOrDefault就可以了。谢谢。XML的问题我并没有太多办法解决,它是第三方数据导入源。 - Justin
3
  1. 买一本关于XML的书,任何一本都可以。
  2. 找到第三方。
  3. 用这本书打他们,直到他们落花流水。
- user1228
1
这不是可怕的XML,只是有点让人烦恼。"可怕"是指像<order1>...</order1><order2>...</order2>...这样的宝石。或者像<name_of_entity_encoded_in_tag>...</name_of_entity_encoded_in_tag>这样? - Pavel Minaev
Pav,请删除你的评论。不要给任何人任何提示,表明这种邪恶甚至是可能的! - user1228
@PavelMinaev +1,感谢您提供的字符串转换技巧,避免了大量的空值测试逻辑。 - Eight-Bit Guru

3
如果您拥有XML文件:
<SimpleDataList>
   <SimpleData name="zip">60004</SimpleData>  
   <SimpleData name="name">ARLINGTON HEIGHTS</SimpleData>  
   <SimpleData name="state">IL</SimpleData>  
   <SimpleData name="countyname">COOK</SimpleData>  
   <SimpleData name="lat">42.1121336684356</SimpleData>  
   <SimpleData name="lon">-87.9736682731814</SimpleData>
</SimpleDataList>

如果在XElement / XDocument SimpleDataList 中加载数据,您可以使用XPath查询:

SimpleDataList.XPathSelectElement(@"//SimpleDataList/SimpleData[@Name=""name""]");

但我不确定你是否有一个XElement或一个简单的IEnumerable... 无论如何... 我想提一下XPath,以帮助你。


1
在查询XDocument时使用XPath并没有太大意义,因为它是专门针对LINQ设计的。XPath也会稍微慢一些(因为它首先必须被解析为字符串)。 - Pavel Minaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接