[英]How to select a single XML node in c# using multiple XPath queries
我試圖從基於兩個查詢的 XML 文件中選擇一個節點,我有一個產品 ID,我需要它的最新條目 - 最高發行號。
這是我的 XML 文件的格式:
<MyProducts>
<Product code="1011234">
<ProductName>Product Name A</ProductName>
<ProductId>101</ProductId>
<IssueNumber>1234</IssueNumber>
</Product>
<Product code="1029999">
<ProductName>Product Name B</ProductName>
<ProductId>102</ProductId>
<IssueNumber>9999</IssueNumber>
</Product>
<Product code="1015678">
<ProductName>Product Name A2</ProductName>
<ProductId>101</ProductId>
<IssueNumber>5678</IssueNumber>
</Product>
</MyProducts>
我需要從具有最高 IssueNumber 的 ProductId 獲取<product>
節點。 例如,如果 ProductId 是 101,我想要第三個節點,如果它是 102,我想要第二個節點。 文件中有大約 50 種不同的產品,分為三個不同的產品 ID。
我已經使用 SelectSingleNode 嘗試了許多 XPath 組合,方法是使用特定的 ProductID 和 IssueNumber 節點,或者使用產品節點的 code 屬性(它是 Id 和 Issue 的組合),但沒有成功。 代碼當前使用 code 屬性,但這僅僅是因為我們還傳遞了問題編號,我希望能夠在沒有問題編號的情況下執行此操作(以減少前端維護),因為它始終是我們想要的最高問題。 當前代碼是這樣的:
XmlNode productNode = productXml.SelectSingleNode("/MyProducts/Product[@code='" + productCode + "']");
我也使用過這些,它們有點工作,但選擇內部節點,而不是外部 Product 節點:
XmlNodeList productNodes = productXml.SelectNodes("/MyProducts/Product/ProductId[text()='101']");
XmlNodeList productNodes = productXml.SelectNodes("/MyProducts/Product[not (../Product/IssueNumber > IssueNumber)]/IssueNumber");
我想將兩者結合使用,如下所示:
XmlNode productNode = productXml.SelectSingleNode("/MyProducts/Product/ProductId[text()='101'] and /MyProducts/Product[not (../Product/IssueNumber > IssueNumber)]/IssueNumber");
但這會返回錯誤“...拋出'System.Xml.XPath.XPathException'類型的異常”,但我也希望它無論如何都不會返回 Product 節點。 這甚至可以在一行中完成,還是我必須遍歷節點才能找到正確的節點?
使用 Xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication167
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var products = doc.Descendants("Product")
.OrderByDescending(x => (int)x.Element("IssueNumber"))
.GroupBy(x => (int)x.Element("ProductId"))
.Select(x => x.First())
.ToList();
Dictionary<int, XElement> dict = products
.GroupBy(x => (int)x.Element("ProductId"), y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
XElement highestId = dict[101];
}
}
}
你的最后一個想法幾乎就在那里。 您需要將這兩個子句放在[]
選擇器中。 還有max()
可用,我認為它澄清了邏輯。 這應該有效:
/MyProducts/Product[ProductId='101'
and IssueNumber=max(/MyProducts/Product[ProductId='101']/IssueNumber)]
這將選擇Product
,其既有ID 101並具有所有ID-101產品的最高IssueNumber。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.