XPath语法 在C#中使用XPath示例

XPath可以快速定位到Xml中的节点或者属性。XPath语法很简单,但是强大够用,它也是使用xslt的基础知识。

示例Xml:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

​<?​​​​xml​​​ ​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"utf-8"​​​ ​​?> ​​​ ​​<​​​​pets​​​​> ​​​ ​​<​​​​cat​​​ ​​color​​​​=​​​​"black"​​​​weight​​​​=​​​​"10"​​​​> ​​​ ​​<​​​​price​​​​>100</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a black cat</​​​​desc​​​​>​​​ ​​</​​​​cat​​​​> ​​​ ​​<​​​​cat​​​ ​​color​​​​=​​​​"white"​​​​weight​​​​=​​​​"9"​​​​> ​​​ ​​<​​​​price​​​​>80</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a white cat</​​​​desc​​​​>​​​ ​​</​​​​cat​​​​> ​​​ ​​<​​​​cat​​​ ​​color​​​​=​​​​"yellow"​​​​weight​​​​=​​​​"15"​​​​> ​​​ ​​<​​​​price​​​​>80</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a yellow cat</​​​​desc​​​​>​​​ ​​</​​​​cat​​​​> ​​​ ​​<​​​​dog​​​ ​​color​​​​=​​​​"black"​​​​weight​​​​=​​​​"10"​​​​> ​​​ ​​<​​​​price​​​​>100</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a black dog</​​​​desc​​​​>​​​ ​​</​​​​dog​​​​> ​​​ ​​<​​​​dog​​​ ​​color​​​​=​​​​"white"​​​​weight​​​​=​​​​"9"​​​​> ​​​ ​​<​​​​price​​​​>80</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a white dog</​​​​desc​​​​>​​​ ​​</​​​​dog​​​​> ​​​ ​​<​​​​dog​​​ ​​color​​​​=​​​​"yellow"​​​​weight​​​​=​​​​"15"​​​​> ​​​ ​​<​​​​price​​​​>80</​​​​price​​​​>​​​ ​​<​​​​desc​​​​>this is a yellow dog</​​​​desc​​​​>​​​ ​​</​​​​dog​​​​> ​​​ ​​</​​​​pets​​​​>​


XPath的语法:

1. XPath中的符号



符号



说明



示例



示例说明



/



表示从根节点开始选择



/pets



选择根节点pets



表示节点和子节点之间的间隔符



/pets/dog



选择pets节点下的dog节点



//xx



表示从整个xml文档中查找,而不考虑当前节点位置



//price



选择文档中所有的price节点



.



单个英文半角句点表示选择当前节点



/pets/.



选择pets节点



..



双点,表示选择父节点



/pets/dog[0]/..



表示pets节点,也就是第一个dog节点的父节点



@xx



表示选择属性



//dog/@color



表示选择所有dog节点的color属性集合



[…]



中括号表示选择条件,括号内为条件



//dog[@color=’white’]



所有color为white的dog节点



//dog[/price<100]



所有price字节点值小于100的dog节点



中括号内数字为节点索引,类似c#等语言中的数组,数组下标是从1开始的



//dog[1]



第1个dog节点



//dog[last()]



最后一个dog节点,last()是xPath内置函数



|



单竖杠表示合并节点结合



//dog[@color=’white’] | //cat[@color=’white’]



color属性为white的dog节点和color属性为white的cat节点



*



星号表示任何名字的节点或者属性



//dog/*



表示dog节点的所有子节点



//dog/@*



表示dog节点的所有属性节点


2. XPath数学运算符 + 加号表示加 - 表示数字相减 * 表示乘以 div 表示除以,这里数学上的除号/已经被用作节点之间分隔符了 mod 表示取余 3. XPath逻辑运算符 = 等于,相当于c#中的 == != 不等于 > 大于 >= 大于等于 < 小于 <= 小于等于 and 并且 与关系 or 或者 或关系 4. XPath Axes 从字面翻译这个是XPath轴的意思,但根据我的理解这个翻译成XPath节点关系运算关键字更合适,就是一组关键字加上::双冒号表示和当前节点有关系的一个或者一组节点. 使用语法: axisname::nodetest[predicate] 即轴名字::节点名字[取节点条件] 具体说明如下:


关键字



说明



示例



示例说明



ancestor



当前节点的父祖节点



ancestor::pig



当前节点的祖先节点中的pig节点



ancestor-or-self



当前节点以及其父祖节点



ancestor::pig




attribute



当前节点的所有属性



attribute::weight



相当于@weight,attribute::和@是等价的



child



当前节点的所有字节点



child::*[name()!=’price’]



选择名字不是price的子节点



descendant



子孙节点



descendant::*[@*]



有属性的子孙节点



descendant-or-self



子孙节点以及当前节点



descendant-or-self::*




following



Xml文档中当前节点之后的所有节点



following::*




following-sibling



当前节点的同父弟弟节点



following-sibling::




preceding



Xml文档中当前节点之前的所有节点



preceding::*




namespace



选取当前节点的所有命名空间节点



namespace::*




parent



当前节点的父节点



parent::



相当于双点..



preceding-sibling



当前节点之后的同父兄节点



preceding-sibling::*




self



当前节点



self::*



相当于单点.


5. 常用的XPath函数介绍: 在XPath表达式中常用的函数有下面两个: position() 表示节点的序号例如 //cat[position() = 2] 表示取序号为2的dog节点 last() 表示取最后一个节点 //cat[last()] name() 表示当前节点名字 /pets/*[name() != 'pig'] 表示/pets下名字不是pig的子节点 XPath的函数还有很多,包括字符串函数,数字函数和时间函数等,具体可以参考w3的网站。 以上是XPath的语法,下面我们看下如何在.Net中使用XPath 在.Net中可以通过XPathDocument或者XmlDocument类使用XPath。XPathDocument是只读的方式定位Xml节点或者属性文本等,而XmlDocument则是可读写的。 如下代码示例展示了如何使用XPathDocument和XmlDocument。 ​​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

​using​​​ ​​System; ​​​ ​​using​​​ ​​System.Collections.Generic; ​​​ ​​using​​​ ​​System.Linq; ​​​ ​​using​​​ ​​System.Text; ​​​ ​​using​​​ ​​System.Xml.XPath; ​​​ ​​using​​​ ​​System.Xml; ​​​ ​​namespace​​​ ​​UseXPathDotNet ​​​ ​​{ ​​​ ​​class​​​ ​​Program ​​​ ​​{ ​​​ ​​static​​​ ​​void​​​ ​​Main(​​​​string​​​​[] args)​​​ ​​{ ​​​ ​​UseXPathWithXPathDocument(); ​​​ ​​UseXPathWithXmlDocument(); ​​​ ​​Console.Read(); ​​​ ​​} ​​​ ​​static​​​ ​​void​​​ ​​UseXPathWithXmlDocument()​​​ ​​{ ​​​ ​​XmlDocument doc = ​​​​new​​​ ​​XmlDocument(); ​​​ ​​doc.Load(​​​​;​​​ ​​//使用xPath选择需要的节点 ​​​ ​​XmlNodeList nodes = doc.SelectNodes(​​​​"/rss/channel/item[position()<=10]"​​​​);​​​ ​​foreach​​​ ​​(XmlNode item ​​​​in​​​​nodes) ​​​ ​​{ ​​​ ​​string​​​ ​​title = item.SelectSingleNode(​​​​"title"​​​​).InnerText;​​​ ​​string​​​ ​​url = item.SelectSingleNode(​​​​"link"​​​​).InnerText;​​​ ​​Console.WriteLine(​​​​"{0} = {1}"​​​​, title, url);​​​ ​​} ​​​ ​​} ​​​ ​​static​​​ ​​void​​​ ​​UseXPathWithXPathDocument()​​​ ​​{ ​​​ ​​XPathDocument doc = ​​​​new​​​ ​​XPathDocument(​​​​"​​​​);​​​ ​​XPathNavigator xPathNav = doc.CreateNavigator();​​​ ​​//使用xPath取rss中最新的10条随笔 ​​​ ​​XPathNodeIterator nodeIterator = xPathNav.Select(​​​​"/rss/channel/item[position()<=10]"​​​​);​​​ ​​while​​​ ​​(nodeIterator.MoveNext()) ​​​ ​​{ ​​​ ​​XPathNavigator itemNav = nodeIterator.Current;​​​ ​​string​​​ ​​title = itemNav.SelectSingleNode(​​​​"title"​​​​).Value;​​​ ​​string​​​ ​​url = itemNav.SelectSingleNode(​​​​"link"​​​​).Value;​​​ ​​Console.WriteLine(​​​​"{0} = {1}"​​​​,title,url);​​​ ​​} ​​​ ​​} ​​​ ​​} ​​​ ​​}​


XPath使用示例,请看下面的代码注释

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

​using​​​ ​​System; ​​​ ​​using​​​ ​​System.Collections.Generic; ​​​ ​​using​​​ ​​System.Linq; ​​​ ​​using​​​ ​​System.Text; ​​​ ​​using​​​ ​​System.IO; ​​​ ​​using​​​ ​​System.Xml; ​​​ ​​namespace​​​ ​​UseXPath1 ​​​ ​​{ ​​​ ​​class​​​ ​​Program ​​​ ​​{ ​​​ ​​static​​​ ​​void​​​ ​​Main(​​​​string​​​​[] args)​​​ ​​{ ​​​ ​​string​​​ ​​xml = ​​​​@"<?xml version=""1.0"" encoding=""utf-8"" ?>​​​ ​​<pets> ​​​ ​​<cat color=""black"" weight=""10"" count=""4""> ​​​ ​​<price>100</price> ​​​ ​​<desc>this is a black cat</desc> ​​​ ​​</cat> ​​​ ​​<cat color=""white"" weight=""9"" count=""5""> ​​​ ​​<price>80</price> ​​​ ​​<desc>this is a white cat</desc> ​​​ ​​</cat> ​​​ ​​<cat color=""yellow"" weight=""15"" count=""1""> ​​​ ​​<price>110</price> ​​​ ​​<desc>this is a yellow cat</desc> ​​​ ​​</cat> ​​​ ​​<dog color=""black"" weight=""10"" count=""7""> ​​​ ​​<price>114</price> ​​​ ​​<desc>this is a black dog</desc> ​​​ ​​</dog> ​​​ ​​<dog color=""white"" weight=""9"" count=""4""> ​​​ ​​<price>80</price> ​​​ ​​<desc>this is a white dog</desc> ​​​ ​​</dog> ​​​ ​​<dog color=""yellow"" weight=""15"" count=""15""> ​​​ ​​<price>80</price> ​​​ ​​<desc>this is a yellow dog</desc> ​​​ ​​</dog> ​​​ ​​<pig color=""white"" weight=""100"" count=""2""> ​​​ ​​<price>8000</price> ​​​ ​​<desc>this is a white pig</desc> ​​​ ​​</pig> ​​​ ​​</pets>"​​​​; ​​​ ​​using​​​ ​​(StringReader rdr = ​​​​new​​​ ​​StringReader(xml)) ​​​ ​​{ ​​​ ​​XmlDocument doc = ​​​​new​​​​XmlDocument(); ​​​ ​​doc.Load(rdr); ​​​ ​​//取所有pets节点下的dog字节点 ​​​ ​​XmlNodeList nodeListAllDog = doc.SelectNodes(​​​​"/pets/dog"​​​​);​​​ ​​//所有的price节点 ​​​ ​​XmlNodeList allPriceNodes = doc.SelectNodes(​​​​"//price"​​​​);​​​ ​​//取最后一个price节点 ​​​ ​​XmlNode lastPriceNode = doc.SelectSingleNode(​​​​"//price[last()]"​​​​);​​​ ​​//用双点号取price节点的父节点 ​​​ ​​XmlNode lastPriceParentNode = lastPriceNode.SelectSingleNode(​​​​".."​​​​);​​​ ​​//选择weight*count=40的所有动物,使用通配符* ​​​ ​​XmlNodeList nodeList = doc.SelectNodes(​​​​"/pets/*[@weight*@count=40]"​​​​);​​​ ​​//选择除了pig之外的所有动物,使用name()函数返回节点名字 ​​​ ​​XmlNodeList animalsExceptPigNodes = doc.SelectNodes(​​​​"/pets/*[name() != 'pig']"​​​​);​​​ ​​//选择价格大于100而不是pig的动物 ​​​ ​​XmlNodeList priceGreaterThan100s = doc.SelectNodes(​​​​"/pets/*[price div @weight >10 and name() != 'pig']"​​​​);​​​ ​​foreach​​​ ​​(XmlNode item ​​​​in​​​ ​​priceGreaterThan100s) ​​​ ​​{ ​​​ ​​Console.WriteLine(item.OuterXml); ​​​ ​​} ​​​ ​​//选择第二个dog节点 ​​​ ​​XmlNode theSecondDogNode = doc.SelectSingleNode(​​​​"//dog[position() = 2]"​​​​);​​​ ​​//使用xpath ,axes 的 parent 取父节点 ​​​ ​​XmlNode parentNode = theSecondDogNode.SelectSingleNode(​​​​"parent::*"​​​​);​​​ ​​//使用xPath选择第二个dog节点前面的所有dog节点 ​​​ ​​XmlNodeList dogPresibling = theSecondDogNode.SelectNodes(​​​​"preceding::dog"​​​​);​​​ ​​//取文档的所有子孙节点price ​​​ ​​XmlNodeList childrenNodes = doc.SelectNodes(​​​​"descendant::price"​​​​);​​​ ​​} ​​​ ​​Console.Read(); ​​​ ​​} ​​​ ​​} ​​​ ​​}​


C#处理Xml的相关随笔