如何使用LINQ选择内部XML节点的集合?

时间:2011-03-04 19:29:30

标签: c# linq linq-to-xml

我有以下xml。鉴于UIDManufacturer NameImage Layout,我想提取xml中存在的所有可能的大小。

<Rules>
  <UniqueID UID="123413">
    <Manufacturer Name="XYZ Company">
      <Image Layout="Portrait">
        <Size rows="512" cols="512" price="x" />
        <Size rows="1024" cols="1024" price="y" />
      </Image>
    </Manufacturer>
  </UniqueID>
</Rules>

我现在这样做的方式是:

XElement rules = XElement.Parse(xmlDoc.OuterXml);

var uids = rules.Elements("UniqueID")
                .Where(x=> (string)x.Attribute("UID")=="123413")
                .ToList();

foreach(var uid in uids)
{
    var manufacturers = uid.Elements(("UniqueID")
                           .Where(x=> (string)x.Attribute("Name")=="XYZ Company")
                           .ToList();
}

等等,直到我收集了可能的大小。

所以我使用3个foreach循环。有没有一种更好的方法可以使用LINQ来实现这一行代码?

3 个答案:

答案 0 :(得分:2)

它有点拗口,但你可以使用XPathSelectElements:

 var sizes = rules.XPathSelectElements("//UniqueId[@UID = '123413']/Manufacturer[@Name = 'XYZ Company']//Size");

显然,您可以使用字符串格式来动态插入@UID和@Name的值。

确保包含System.Xml.XPath

答案 1 :(得分:1)

我喜欢James的XPath方法。如果你只是继续堆叠LINQ,它可能会是这样。

var sizes = xmlDoc.Elements("Rules")
    .Elements("UniqueID")
    .Where(e => e.Attribute("UID").Value=="123413")
    .Elements("Manufacturer")
    .Where(e => e.Attribute("Name").Value=="XYZ Company")
    .Elements("Image")
    .Where(e => e.Attribute("Layout").Value=="Portrait")
    .Elements("Size");

sizes最终成为IEnumerable(2项)

<Size rows="512" cols="512" price="x" />
<Size rows="1024" cols="1024" price="y" />

答案 2 :(得分:0)

试试这个(使用XPath):

String xmlString = @"<Rules> <UniqueID UID=""123413""> <Manufacturer Name=""XYZ Company""> <Image Layout=""Portrait""> <Size rows=""512"" cols=""512"" price=""x"" /> <Size rows=""1024"" cols=""1024"" price=""y"" /> </Image> </Manufacturer> </UniqueID> </Rules>";
XElement element = XElement.Parse(xmlString);

var uids = element.XPathSelectElements("//UniqueID[@UID=123413]/Manufacturer[@Name='XYZ Company']/Image[@Layout='Portrait']/Size")
          .Select(a=> new {rows=a.Attribute("rows").Value, cols=a.Attribute("cols").Value})
        .ToList();  
foreach(var uid in uids) 
{     
    Console.WriteLine(uid.rows + " - " + uid.cols);
}