Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.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# 使用SelectNodes和Xpath进行Xml解析_C#_Xml_Xpath - Fatal编程技术网

C# 使用SelectNodes和Xpath进行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

我正在编写一个程序来解析包含书籍内容的XML文件

我所做的

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();