C# 使用SelectNodes和Xpath进行Xml解析
我正在编写一个程序来解析包含书籍内容的XML文件 我所做的C# 使用SelectNodes和Xpath进行Xml解析,c#,xml,xpath,C#,Xml,Xpath,我正在编写一个程序来解析包含书籍内容的XML文件 我所做的 XmlDoc = new XmlDocument(); XmlDoc.Load(path); bookList = XmlDoc.GetElementsByTagName("book"); List<string> prices= new List<string>(); foreach (XmlNode node in bookList) { XmlNode price = n
XmlDoc = new XmlDocument();
XmlDoc.Load(path);
bookList = XmlDoc.GetElementsByTagName("book");
List<string> prices= new List<string>();
foreach (XmlNode node in bookList)
{
XmlNode price = node["price"];
prices.Add(price.InnerText);
}
// to get the highest priced book(s)
prices.Sort();
感谢您的帮助,谢谢
编辑:我通过对bookList中的节点进行foreach循环,并使用if case将price.InnerText与highest进行比较,成功地解决了这个问题。
它工作得很好,但我仍然想知道是否可以用XPath实现这一点。谢谢
编辑2:我知道使用不同的方法可以改进它,我只是想知道是否可以用XPath比较字符串变量和节点值。如果您决定使用Linq2XML,代码看起来会非常类似: 因为我实际上没有您的XML,所以我想到了这一点
// load from a file
var xDoc = XDocument.Load(path);
// find all nodes where the tagname is book
var books = xDoc.Descendants("book")
var expensiveList = books
// make sure that the book has a price node
.Where(b => b.Descendants("price").FirstOrDefault() != null
// compare the first price node Value to highest
&& b.Descendants("price").First().Value.Equals("highest",
StringComparison.OrdinalIgnoreCase))
// lets only return up to 10
.Take(10)
// return what we found as List<XElement>
.ToList();
如果价格实际上是一个整数,那么:
int tempParse;
...
// make sure that the book has only 1 price
.Where(b => b.Descendants("price").Count() == 1
// price is actually an integer (you can replace with decimal)
&& int.TryParse(b.Descendants("price").First().Value, out tempParse))
// make a temporary anonymous object to sort price
.Select(b => new
{
Book = b,
Price = int.Parse(b.Descendants("price").First().Value)
})
// order the anonymous object by price
.OrderByDescending(b => b.Price)
// select only the books
.Select(b => b.Book)
// lets only return up to 10
.Take(10)
// return what we found as List<XElement>
.ToList();
一些建议:
您不应该使用字符串数组来存储价格。整数数组
那就更好了。
在将price.InnerText添加到列表之前验证它-它可能不是数值。
一旦有了整数数组,就可以对其进行排序并选择最大值。
要选择价格最高的书,可以使用以下语法
XmlNodeList expensiveList=XmlDoc.SelectNodes//book[price=highest]
如果您不想单独找出最高价格,有一种方法可以直接获取价值最高的节点。看这条线
希望这对您有所帮助您为什么不使用Linq2Xml?Linq提供了一种非常简单的方法来选择、排序、排序和过滤XML节点。你试过了吗?@Erik我不熟悉Linq2Xml,但我会调查一下。我研究了将近一个小时的Xpath,找到了很多方法来比较值,但不比较变量,因此问题就来了。@dbc的可能重复我想比较字符串变量和文件中的节点值,这与范围比较b/w有什么关系?有趣。这看起来确实更彻底和直接。我一定要试一试。谢谢你,埃里克
int tempParse;
...
// make sure that the book has only 1 price
.Where(b => b.Descendants("price").Count() == 1
// price is actually an integer (you can replace with decimal)
&& int.TryParse(b.Descendants("price").First().Value, out tempParse))
// make a temporary anonymous object to sort price
.Select(b => new
{
Book = b,
Price = int.Parse(b.Descendants("price").First().Value)
})
// order the anonymous object by price
.OrderByDescending(b => b.Price)
// select only the books
.Select(b => b.Book)
// lets only return up to 10
.Take(10)
// return what we found as List<XElement>
.ToList();