Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用LINQ选择内部XML节点的集合?_C#_Linq_Linq To Xml - Fatal编程技术网

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

C# 如何使用LINQ选择内部XML节点的集合?,c#,linq,linq-to-xml,C#,Linq,Linq To Xml,我有以下xml。给定UID、制造商名称和图像布局,我想提取xml中存在的所有可能的大小 <Rules> <UniqueID UID="123413"> <Manufacturer Name="XYZ Company"> <Image Layout="Portrait"> <Size rows="512" cols="512" price="x" /> <Size rows="

我有以下xml。给定
UID
制造商名称
图像布局
,我想提取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>
等等,直到我收集到可能的尺寸


所以我使用了3个foreach循环。是否有更好的方法可以通过使用LINQ的一行代码来实现这一点?

虽然有点多,但您可以使用XPathSelectElements:

 var sizes = rules.XPathSelectElements("//UniqueId[@UID = '123413']/Manufacturer[@Name = 'XYZ Company']//Size");
显然,您可以使用字符串格式来动态插入@UID和@Name的值


确保包含
System.Xml.XPath

我喜欢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");
大小
最终为IEnumerable(2项)


试试这个(使用XPath):

String xmlString=@”;
XElement元素=XElement.Parse(xmlString);
var uids=element.XPathSelectElements(“//UniqueID[@UID=123413]/Manufacturer[@Name='XYZ Company']/Image[@Layout='trait']/Size”)
.Select(a=>new{rows=a.Attribute(“rows”).Value,cols=a.Attribute(“cols”).Value})
.ToList();
foreach(uids中的变量uid)
{     
Console.WriteLine(uid.rows+“-”+uid.cols);
} 

你为什么不在每行末尾使用分号?@Rafe:可能是因为OP最初在代码中贴了记号。所以它们可能都是独立的代码行,而不是连续的代码块。这比堆叠lINQ语句有很大的性能优势吗?我不这么认为。它的主要优点是简洁。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");
<Size rows="512" cols="512" price="x" />
<Size rows="1024" cols="1024" price="y" />
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);
}