【问题标题】:Xml Parsing using SelectNodes and Xpath使用 SelectNodes 和 Xpath 进行 Xml 解析
【发布时间】:2015-04-23 04:51:38
【问题描述】:

我正在编写一个程序来解析 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();

我现在想做的是使用 SelectNodes 来查找价格最高的书籍,并将其作为 XMLNodeList 返回

//to store the highest price of a book
string highest = prices[0];

**// this is what i can't figure out
XmlNodeList expensiveList = XmlDoc.SelectNodes("descendant::book[price = highest]");**

感谢任何帮助,谢谢!

编辑:我设法通过为 bookList 中的节点创建一个 foreach 循环来解决它,并使用 if 案例将 price.InnerText 与最高值进行比较。 它工作得很好,但我仍然想知道这是否可以用 XPath 完成。谢谢!

编辑#2:我知道可以使用不同的方法对其进行改进,我只是想知道是否可以使用 XPath 将字符串变量与节点值进行比较。

【问题讨论】:

  • 有什么理由不使用 Linq2Xml? Linq 提供了一种非常简单的方法来选择、排序、排序和过滤 XML 节点。
  • social.msdn 中提到了一种排序。你试过吗?
  • @Erik 我对 Linq2Xml 不熟悉,但我会研究一下。我研究了 Xpath 近一个小时,发现了许多比较值而不是变量的方法,因此提出了问题。
  • @dbc 我想将字符串变量与文件中的节点值进行比较,这与范围比较 b/w 相同节点有何关系?

标签: c# xml xpath


【解决方案1】:

如果您决定使用 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();

【讨论】:

  • 有趣。这确实看起来更彻底和直接的方法。我一定会试一试的。谢谢埃里克
【解决方案2】:

一些建议:

  1. 您不应使用字符串数组来存储价格。整数数组 会更好。
  2. 在将 price.InnerText 添加到列表之前对其进行验证 - 它可能不是数值。
  3. 一旦你有一个整数数组 - 你可以对它进行排序并选择最大值。 要选择价格最高的书,您可以使用类似

    的语法

    XmlNodeList 昂贵列表 = XmlDoc.SelectNodes("//book[price =最高]");

如果您不想单独找出最高价格 - 有一种方法可以直接抓取最高价值的节点。请参阅此线程。

Selecting the min/max value of an attribute under multiple nodes in XPath 1.0

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 2013-02-20
    • 1970-01-01
    相关资源
    最近更新 更多