Linq用于嵌套属性

时间:2015-12-09 17:42:50

标签: c# linq

下面是我的xml

<?xml version="1.0"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <DataContainer xsi:type="ClassA">
    <Identifier></Identifier>
    <prop2></prop2>
    <prop3></prop3>
    <Key>549</Key>
  </DataContainer>
  <DataContainer xsi:type="ClassB">
    <Identifier></Identifier>
    <prop2></prop2>
    <prop3></prop3>
    <ClassC>
      <ClassD>
        <Identifier></Identifier>
        <prop2></prop2>
        <prop3></prop3>
        <Key>461</Key>
      </ClassD>
       <ClassD>
        <Identifier></Identifier>
        <prop2></prop2>
        <prop3></prop3>
        <Key>468</Key>
      </ClassD>
       <ClassD>
        <Identifier></Identifier>
        <prop2></prop2>
        <prop3></prop3>
        <Key>460</Key>
      </ClassD>
    </ClassC>
    <ClassE>
      <ClassF>
        <Identifier></Identifier>
        <prop2></prop2>
        <prop3></prop3>
        <Key>549</Key>
      </ClassF>
    </ClassE>
  </DataContainer>
..
..
..
.. Some more class that may or may not contain Key property
</Data>

我知道它复杂的xml结构,但它是怎么回事,抱歉。我必须根据Key属性值获取Identifier属性的值,例如Key = 549或者其他什么。我知道我能做到

Data.OfType<ClassA>().where(h=>h.Key==someValue).Select(...

但是我必须为每个不同的类类型执行此操作,因为Key属性位于不同的类中吗?除此之外,如果将来另一个类进来,我必须找到基于该类的标识符,我是否必须添加另一个linq查询来查找该标识符?有没有更好的解决方案,或者我坚持每个类类型的个别查询?

我已经拥有了数据&#39;反序列化的对象完全看起来像基于上面的xml&amp;我正在寻找一种方式,给我一个标识符&#39;基于Key的属性值..

帮助将不胜感激,

3 个答案:

答案 0 :(得分:3)

您可以使用Linq-to-XML轻松完成此操作: -

 XDocument xdoc = XDocument.Load("YourXML");
 IEnumerable<string> Identifiers = xdoc.Root.Elements("DataContainer")
                                       .Where(x => (string)x.Element("Key") == "549")
                                       .Select(x => (string)x.Element("Identifier"));

答案 1 :(得分:0)

根据Rahul的回答,您可能会考虑这样的事情:

public class DataBase
{
   public string Identifier { get; set; }
   public string Key { get; set; } 
}

public IEnumerable<DataBase> FindInstancesByKey(IEnumerable<DataBase> data, string key)
{
   return data.Where(d => d.Key == key);
}

public void Main()
{
   // Deserialize the data
   var data = Deserialize();

   var instances = FindInstancesByKey(data, "mykey");
   Console.WriteLine(instances.Select(x => x.Instance);
}

创建一个所有XML实例继承的基类,为您提供所需的强类型设置,以便开始一般性地查询InstanceKey属性。

答案 2 :(得分:0)

要获取具有最接近标识符值的所有keyElements,您可以使用以下内容: // Key允许搜索XML&amp;中的所有键。 ../标识符允许找到密钥的最近兄弟。

        var xDoc = XDocument.Load(@"C:\temp\test.xml");
        var keyElements = xDoc.XPathSelectElements("//Key").ToList();
        var items = new List<Tuple<string, string>>();
        foreach (var keyElement in keyElements)
        {
            var identifier = keyElement.XPathSelectElement("../Identifier");

            items.Add(new Tuple<string, string>(keyElement.Value, (identifier != null ? identifier.Value : null)));
        }