如何使用 XPath 选择 XML 节点 – C#
XPath(XML 路径语言)基于 XML 文档的 DOM 表示法。因此,您可以使用 XPath 在 XML 文件中查找与 XPath 表达式中定义的某些条件相匹配的一个或多个特定节点。本文将举例说明如何使用 XPath 查询从 XML 文件中选择所需的信息。您将学习如何使用 XPath 浏览 XML 文档和选择节点。
要了解如何使用 Evaluate() 方法浏览 HTML 文档并使用 XPath 查询选择节点,请参阅文章 如何使用 XPath – Evaluate() 方法。
您可以从 GitHub 下载数据文件和完整的 C# 示例,这些示例演示了 XPath 查询中 Evaluate() 方法的使用。
XPath 查询 – 从 XML 文件中选择节点
这些示例将说明如何使用 XPath 查询语言从 XML 文件中选择所需的信息。让我们来看看 XML 文档 cars.xml。该测试 XML 文档包含一个汽车经销商数据库,其中有经销商的电话号码、姓名以及他们拥有的汽车清单。
让我们按顺序编写 XPath 表达式,选择您感兴趣的姓名、电话号码和汽车列表。XPath 功能强大,您将在下面的示例中看到这一点:
选择 XML 文件中的所有 “Dealer” 节点
XPath 可用于以编程方式评估表达式,并在 XML 文档中选取特定节点。要从 XML 中选择节点,请使用 Evaluate()方法。
让我们从一个直接的 XPath 查询开始,查询 XML 文档中的所有 “Dealer” 节点。下面使用的是 XPath 表达式 //Dealer
。它会选择所有 Dealer
元素,无论它们在文档中的什么位置:
C# code
1var dealers = doc.Evaluate("//Dealer", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer", document, null, XPathResult.ANY_TYPE, null);
因此,您可以不受限制地从 XML 文件中选择所有经销商的信息。XPath 表达式 //经销商
允许您选择所有名为 “Dealer” 的嵌套节点。
使用 XPath 轴选择节点 – descendant::
限制汽车生产日期的 XPath 查询
让我们把 XPath 查询复杂化,增加一个关于汽车生产年份的限制条件。
您可以在 XPath 表达式中使用 XPath Axes。XPath 轴表示与当前节点的关系,用于在文档树中定位相对于该节点的节点。后代 “轴表示上下文节点的所有子节点及其所有子节点,以此类推。换句话说,后代选择当前节点的所有后代(子节点、孙节点等)。例如,descendant::Car
选择当前节点的所有 Car 后代。
因此,让我们创建一个 XPath 表达式,以查找拥有车型生产日期大于 2005 年的汽车 descendant::Car
的经销商 descendant::Model > 2005
。在 DOM 树中,我们要查找所有名为 “Car” 的 “Dealer” 子代中,有一个名为 “Model” 的子代的值大于 “2005”。下面使用 XPath 表达式//Dealer[descendant::Car[descendant::Model > 2005]]
。
C# code
1var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer[descendant::Car[descendant::Model > 2005]]", document, null, XPathResult.ANY_TYPE, null);
限制汽车生产日期和价格的 XPath 查询
下一步,让我们添加更多限制:引入汽车价格限制 and descendant::Price < 25000
.
XPath 表达式如下//Dealer[descant::Car[descant::Model > 2005 and descendant::Price<25000]]
。 注意: 价格和生产年份的条件用 and
组合,这意味着这两个条件要同时执行:
C# code
1var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", document, null, XPathResult.ANY_TYPE, null);
因此,只有生产日期不早于 2005 年、价格低于 25,000 美元的汽车经销商才能入选。
C# 示例,第 1 部分 – 从 XML 文件中选择节点
让我们来看看如何从 XML 文件中选择生产日期不早于 2005 年、价格低于 25,000 美元的汽车经销商,并将所需信息打印到控制台。您应该遵循以下几个步骤:
- 加载现有 XML 文件( cars.xml)。
- 使用
Document 类的
Evaluate() 方法,并将 XPath 表达式
//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]
和其他参数传递给它。 - 遍历结果节点,并将其内容打印到控制台。
- 您将获得一份包含 “Dealer” 节点全部内容的经销商列表。
1// Use XPath to select nodes from XML
2
3// Create an instance of a document
4using (HTMLDocument doc = new HTMLDocument(Path.Combine(DataDir, "cars.xml")))
5{
6 // Select dealers that match XPath expression
7 IXPathResult dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
8 Node dealer;
9
10 // Iterate over the selected dealers
11 while ((dealer = dealers.IterateNext()) != null)
12 {
13 Console.WriteLine(dealer.TextContent);
14 }
15}
C# 示例,第 2 部分 – 从选定节点中提取特定信息
在示例的前面部分,XPath 查询选择了与 XPath 表达式//Dealer[descant::Car[descant::Model > 2005 and descendant::Price < 25000]]
匹配的 “Dealer"节点的所有内容。但您可以从所选 “Dealer” 的全部内容中只选择并打印您感兴趣的信息。
在本例(
cars.xml)中,在所选 “Dealer” 节点的循环中添加了一个内部查询。该查询以字符串形式收集经销商的信息,如 “Name"和 “Telephone”:concat('Dealer name: ', Name, 'Telephone: ', Telephone)
。请注意传递给
Evaluate(expression
, contextNode
, resolver
, type
, result
) 方法的第二个参数。这是执行查询的相对节点,即当前的 “Dealer” 节点。该查询将名称为 “Name” 和 “Telephone” 的节点内容连接起来。 注意: 查询使用的预期结果类型为字符串 XPathResultType.String
,结果值通过 StringValue
属性而非节点迭代器获取。
在所选经销商列表中,可以添加指向特定汽车的 “CarID “属性。应使用 XPath 表达式”.///Car[后裔::车型 > 2005 且后裔::价格 < 25000]/@CarID`” 进行查询。添加的查询有几个特点,让我们来看看:
- 查询会选择相对于当前节点
.//Car
,而不是相对于树根节点//Car
的所有嵌套汽车; - 在 XPath 表达式中,我们请求所选汽车的
/@CarID
属性。
1// Query and extract XML data using XPath expressions
2
3// Create an instance of a document
4using (HTMLDocument doc = new HTMLDocument(Path.Combine(DataDir, "cars.xml")))
5{
6 // Select dealers that match XPath expression
7 IXPathResult dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
8 Node dealer;
9
10 // Iterate over the selected dealers
11 while ((dealer = dealers.IterateNext()) != null)
12 {
13 // Get and print Dealer name and Telephone
14 IXPathResult dealerInfo = doc.Evaluate("concat('Dealer name: ', Name/text(), ' Telephone: ', Telephone/text())", dealer, doc.CreateNSResolver(doc), XPathResultType.String, null);
15 Console.WriteLine(dealerInfo.StringValue);
16
17 // Select and print CarID that match XPath expression
18 IXPathResult carIds = doc.Evaluate(".//Car[descendant::Model > 2005 and descendant::Price < 25000]/@CarID", dealer, doc.CreateNSResolver(doc), XPathResultType.Any, null);
19 Node carId;
20
21 while ((carId = carIds.IterateNext()) != null)
22 {
23 Console.WriteLine("Car id: " + carId.TextContent);
24 }
25 }
26}
因此,我们会得到一份经销商名单,上面有我们感兴趣的汽车的名称、电话和 ID 代码。
Aspose.HTML 提供免费的 HTML 网络应用程序,是转换器、合并器、搜索引擎优化工具、HTML 代码生成器、URL 工具等的在线集合。这些应用程序可在任何装有网络浏览器的操作系统上运行,无需安装任何其他软件。它是一种快速、简便的方法,能有效解决与 HTML 相关的任务。