C#使用Linq to XML進行XPath查詢


 

最近在用到HtmlAgliltyPack進行結點查詢時,發現這里選擇結點使用的是XPath。所以這里總結一下在C#中使用XPath查詢XML的方法。習慣了用Linq,這里也是用的Linq to xml的。

Linq To XML的核心類是XDocumentXElementXAttribute,需要引用using System.Xml.Linq命名空間。

這三個類簡單理解為:

XDocument:打開的整個XML文檔

XElement:節點元素

XAttribute:屬性

 

下面簡單介紹一下使用

 

如有以下XML文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <html>
 3   <head>
 4     <title>測試XML</title>
 5   </head>
 6   <body>
 7     <div class="card-container">
 8       <div class="item-title">
 9         <h3 class="item-shop-name">汪家羊肉館</h3>
10       </div>
11       <div class="item-comment">
12         <span class="price1">¥62/人</span>
13         <span class="price2">¥12/人</span>
14         <span class="price3">2</span>
15         <span class="price4">12</span>
16       </div>
17     </div>
18   </body>
19 </html>

 

 

打開XML文件

1 XDocument doc = XDocument.Load("demo.xml");

 

獲取根節點(html節點 返回XElement類型)

var root = doc.Root;

 

獲取第一個子節點(返回XElement類型)

1 var firstNode = root.FirstNode;

 

獲取全部子節點(返回IEnumerable<XNode>)

1 var allChildNode = root.Nodes();

 

獲取指定名稱的第一個子節點(返回XElement類型)

1 var headNode = root.Element("head");

 

獲取指定名稱的全部子節點(返回IEnumerable<XElement>)

var allNamedNode = root.Elements("head");

 

獲取節點指定名稱的屬性(<div class="card-container"> )

1 var attribute = root.Element("body").Element("div").Attribute("class");

 

獲取節點的全部屬性

1  var allAttributes = root.Attributes();

 

使用XPath查詢(需要引用using System.Xml.XPath命名空間)

1 var xpathQeury = root.XPathSelectElement("body/div");

 

獲取節點的名稱和值

1   //獲取結點的名稱
2    var nodeName = root.Name;
3    //獲取節點的值
4    var nodeValue = root.Value;

 

保存XML

1 doc.Save("demo.xml");

 

Linq查詢(獲取<span class="price2">¥12/人</span>節點下的值)

這里僅做示例,返回返回IEnumerable<XElement>類型的都可以進行Linq查詢

不使用XPath

1 var queryResult = root.Element("body").Element("div").Elements("div").ElementAt(1).Elements("span").Where(x=>x.Attribute("class") != null && x.Attribute("class").Value == "price2").FirstOrDefault();
2             if(queryResult != null)
3                 Console.WriteLine(queryResult.Value);

 

使用XPath

1 var xpathQueryResult = root.XPathSelectElements("body/div/div[2]/span").Where(x => x.Attribute("class") != null && x.Attribute("class").Value == "price2").FirstOrDefault();
2             if(xpathQueryResult != null)
3                 Console.WriteLine(xpathQueryResult.Value);

輸出結果都為下

 

下面開始介紹XPath

XPath 是 XML 文檔中查找信息的語言,使用XPath可以對XML的元素進行查找。

這里重着介紹一下XPath語法

 

/    從根節點開始選擇

1 var xpathRoot = doc.XPathSelectElement("/html");
2 var xpathRoot2 = doc.XPathSelectElement("html");

運行結果

 

//   獲取文檔中所有指定的結點,不管它的位置

如要獲取xml文檔中所有的span節點

1             //以下獲取的結果都是一樣的
2             //盡管位置不一樣,但查詢結果是一樣的
3             var body = root.Element("body").Element("div").Elements("div").ElementAt(1);
4             var allDivNodeInBody = body.XPathSelectElements("//div");
5             var allDivNodeInDoc = doc.XPathSelectElements("//div");
6             Console.WriteLine(allDivNodeInBody.Count());
7             Console.WriteLine(allDivNodeInDoc.Count());

運行結果

 

.   當前節點

1  var currentNode = root.XPathSelectElement(".");
2         

運行結果

 

..  當前節點的父節點

1 var parentNode = root.Element("body").XPathSelectElement("..");

運行結果

@  選取屬性

這個操作在Linq to xml里不支持,會產生一個"XPath 表達式的計算結果為意外類型 System.Xml.Linq.XAttribute。"異常

 

通配查詢

*     全部節點

@*  全部屬性(不支持)

 

謂詞查詢

選擇第一個查詢結果,如<span class="price1">¥62/人</span>

//span[1]
1 var firstSpanNode = doc.XPathSelectElement("//span[1]");

運行結果

選擇最后一個查詢結果,如最后一個<span class="price4">12</span>

//span[last()]
1  var lastDivNode = doc.XPathSelectElement("//span[last()]");
2 Console.WriteLine(lastDivNode.Attribute("class").Value);

運行結果

選擇帶有屬性class的div節點

//div[@class]
1 var nodeWithClassAttribute = doc.XPathSelectElements("//div[@class]");
2             foreach (var item in nodeWithClassAttribute)
3             {
4                 Console.WriteLine("====================");
5                 Console.WriteLine(item);
6             }

運行結果

選擇帶有屬性class,且值為item-title的div節點

//div[@class='item-title']
1  var nodeWithClassValueAttribute = doc.XPathSelectElements("//div[@class='item-title']");
2             foreach (var item in nodeWithClassValueAttribute)
3             {
4                 Console.WriteLine(item);
5             }

運行結果

簡單的選擇計算

獲取倒數第二個div節點

//div[last()-1]
1 var nextToLastDivNode = doc.XPathSelectElement("//div[last()-1]");

運行結果

獲取值大於10的span節點

//span[text()>10]
1 var greaterThanTenSpan = doc.XPathSelectElements("//span[text()>10]");

運行結果:

獲取值加10等於22的span節點

//span[text()+10=22]
1 var plusTenSpan = doc.XPathSelectElements("//span[text()+10=22]");

運行結果:

常用運行符如下

+               加

-                減

*               乘

div           除

=              等於

!=             不等於

>              大於

<              小於

>=           大於等於

<=            小於等於

or            或

and          與

 

組合查詢

如查詢值等於12或等於2的span節點

//span[text()=2]|//span[text()=12]
1  var combineQuery = doc.XPathSelectElements("//span[text()=2]|//span[text()=12]");
2             foreach (var item in combineQuery)
3             {
4                 Console.WriteLine(item.Value);
5             }

運行結果

 

示例代碼

 

參考:

https://www.w3.org/TR/2017/REC-xpath-31-20170321/

https://www.w3school.com.cn/xpath/index.asp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM