查一下 w3schools 的 XPath 函式庫, 可以發現一個 function 還蠻符合的:
fn:index-of((item,item,...),searchitem)
只是一套用到程式中, 就會產生以下的 Exception:
Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
發生此問題的原因在於 .Net 並未完全支援 XPath 的函式, 有興趣的可以參考這個網址.
不過我發現有一個函式還不錯: fn:contains(string1,string2)
Returns true if string1 contains string2, otherwise it returns false
Example: contains('XML','XM')
Result: true
所以以下我用 w3schools 中的一個 CD catalog 的範例檔, 試著做出類似 index-of 的查詢方式, 來查出 <COUNTRY> 是 UK 或 EU 的 CD:
- Linq: 利用字串陣列中的 Contains 進行比對
string[] lstQuery = {"UK", "EU"}; XmlDocument doc = new XmlDocument(); doc.Load(@"test.xml"); var query = from cd in doc.SelectNodes("//CD").Cast<XmlNode>() where lstQuery.Contains(cd["COUNTRY"].InnerText) select cd; foreach (XmlNode node in query) { Console.WriteLine(node.OuterXml); }
- XPath:
- 將查詢條件的 UK 和 EU 組合成 '|UK|EU|', 其中 '|' 只是個分隔符號, 可以視查詢條件修改成一個不會有衝突的符號.
- 將 <COUNTRY> 中的文字組合為 '|UK|’ 的形式, 以方便後續進行 contains 的比對.
(這邊要注意字串合併的部分要用 XPath 的 concat, 而不是寫成 '|COUNTRY|’)
string[] lstQuery = {"UK", "EU"}; XmlDocument doc = new XmlDocument(); doc.Load(@"test.xml"); XmlNodeList list = doc.SelectNodes( "//CD[contains('|"+string.Join("|",lstQuery)+"|',concat('|',COUNTRY,'|'))]"); foreach (XmlNode node in list) { Console.WriteLine(node.OuterXml); }
個人只是提供另一種資料處理方式而已. :)
沒有留言:
張貼留言