【发布时间】:2021-12-29 21:05:48
【问题描述】:
我有以下 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<Catalog>
<Device>
<Identity>
<Key>
<VendorID Name="Generic Vendor">123</VendorID>
<ProductType Name="Something">26</ProductType>
<ProductCode>78</ProductCode>
<Revs>
<MajorRev Number="17" DefaultMinorRev="128" />
<MajorRev Number="18" DefaultMinorRev="128" />
<MajorRev Number="19" DefaultMinorRev="128" />
</Revs>
</Key>
</Identity>
</Device>
<Device>
<Identity>
<Key>
<VendorID Name="Generic Vendor">123</VendorID>
<ProductType Name="Something">26</ProductType>
<ProductCode>78</ProductCode>
<Revs>
<MajorRev Number="17" DefaultMinorRev="129" />
<MajorRev Number="18" DefaultMinorRev="129" />
<MajorRev Number="19" DefaultMinorRev="129" />
</Revs>
</Key>
</Identity>
</Device>
</Catalog>
我使用以下 C# 程序阅读它:
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace XMLSample
{
class Program
{
static void Main(string[] args)
{
var xmlFile = new StreamReader("c:\\misc\\minimumxmlsample.xml");
XElement catSvcsData = XElement.Load(xmlFile);
// A device has only one vendor ID, product type, product code and revs element.
var matchingDeviceKeys =
from dev in catSvcsData.Elements("Device")
where dev.Descendants("VendorID").First().Value == "123" && // device.Vendor.ToString(CultureInfo.InvariantCulture) &&
dev.Descendants("ProductType").First().Value == "26" && // device.ProductType.ToString(CultureInfo.InvariantCulture) &&
dev.Descendants("ProductCode").First().Value == "78" // device.ProductCode.ToString(CultureInfo.InvariantCulture)
from rev in dev.Descendants("Revs")
where rev.Element("MajorRev").Attribute("Number").Value == "17" && // device.MajorRevision.ToString(CultureInfo.InvariantCulture) &&
rev.Element("MajorRev").Attribute("DefaultMinorRev").Value == "129" // device.MinorRevision.ToString(CultureInfo.InvariantCulture)
select dev; // dev.Element("Schema").Element("Capabilities").Element("DuplexSupported");
//var matchingDeviceKeys =
// catSvcsData.Elements("RADevice").Where(dev => dev.Descendants("VendorID").First().Value == "65532" &&
// dev.Descendants("ProductType").First().Value == "26" &&
// dev.Descendants("ProductCode").First().Value == "78")
// .Any(dev => dev.Descendants("MajorRev").Attribute("Number").Value == "17" &&
// dev.Descendants("DefaultMinorRev") == "129");
Console.WriteLine("Hello World!");
}
}
}
程序需要找到设备元素,其中一个 MajorRev 元素具有给定的主要修订号和默认的次要修订号。未注释的查询有效,但两个“from”子句对我来说看起来很奇怪,很可能是因为我更习惯于使用 Where() 函数和类似的东西,而不是使用这种形式的 LINQ 查询。在我看来,应该可以使用 Any() 来查看是否有任何 MajorRev 元素与目标匹配。注释掉的查询不起作用,因为我需要使用 First() 来指定我从中获取属性的 MajorRev 元素。有没有更好的方法来编写这个查询?
【问题讨论】:
-
首先将您的 Linq 查询从关键字语法转换为扩展方法语法,否则阅读起来很痛苦。