2011-03-04 68 views
2

我有以下的XML。鉴于,UIDManufacturer NameImage Layout,我想拉出所有可能的大小存在于xml中。如何使用LINQ选择内部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?

+2

你为什么不每年年底使用分号任何理由线? – 2011-03-04 19:32:46

+0

@Rafe:可能是因为OP最初有用刻度标记的代码。所以它们可能都是单独的代码行,而不是连续的代码块。 – mellamokb 2011-03-04 19:33:54

+0

@Rafe - 现在已修复:) – 2011-03-04 19:36:05

回答

2

这是一个拗口的一点点,但您可以使用XPathSelectElements:

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

很明显,你可以使用字符串格式化动态插入值@UID和@Name。

确保包含System.Xml.XPath

+0

这是否比堆叠lINQ语句具有显着的性能优势? – Sandy 2011-03-04 20:08:39

+0

我不这么认为。它的主要优点是简洁。 XPath是一种非常富有表现力的语言,通常比直接使用linq方法更容易阅读代码。 – 2011-03-04 20:17:06

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" /> 
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); 
}