少了這兩個函式, 每次想找 xml 資料中的最大/最小值, 就只能用 Linq 或是 Select 出所有標籤後, 在程式中去一個個比對.
其實 XPath 只要轉個彎, 就能做出類似的功能.
以下用一個簡單的 xml 來說明如何找出各班成績最好/最差的 <Student>:
<?xml version="1.0" encoding="UTF-8"?> <ClassSet> <Class> <Name>Class_A</Name> <Student> <Name>John</Name> <Score>87</Score> </Student> <Student> <Name>Mary</Name> <Score>85</Score> </Student> <Student> <Name>Apple</Name> <Score>100</Score> </Student> <Student> <Name>May</Name> <Score>60</Score> </Student> </Class> <Class> <Name>Class_B</Name> <Student> <Name>Peter</Name> <Score>100</Score> </Student> <Student> <Name>Rex</Name> <Score>100</Score> </Student> <Student> <Name>Kelly</Name> <Score>60</Score> </Student> <Student> <Name>Hebe</Name> <Score>58</Score> </Student> </Class> <Class> <Name>Class_C</Name> <Student> <Name>Sam</Name> <Score>66</Score> </Student> <Student> <Name>Lulu</Name> <Score>89</Score> </Student> <Student> <Name>Tom</Name> <Score>94</Score> </Student> <Student> <Name>Gina</Name> <Score>67</Score> </Student> </Class> </ClassSet>
- 找出各班成績最好的學生:
概念很簡單: 在同一個班級中, 對每個 <Student>來說, 檢查除了自己以外, 有沒有別人的成績比自己好. 也就是: 我的成績要比別人高, 而且不會有人的成績高過我.XmlDocument doc = new XmlDocument(); doc.Load(@"c:\class_score.xml"); XmlNodeList lstNode = doc.SelectNodes("//Class/Student[" + "position()!=../Student[position()] " + "and (Score > ../Student/Score and not(Score < ../Student/Score))]"); foreach (XmlNode node in lstNode) { Console.WriteLine(node.ParentNode["Name"].InnerText); Console.WriteLine(node.OuterXml); }
我將判斷式拆成三行來說明:
1. //Class/Student : 這應該比較沒問題, 只是找出所有 <Class> 下的 <Student>.
2. position()!=../Student[position()] : 這一段是利用 position() 函式, 來濾掉自己以外的 <Student>.
3. (Score > ../Student/Score and not(Score < ../Student/Score)) : 這段就是剛上述的, 比較 <Score> 的值, 不僅自己要比別人的 <Score> 高, 且自己不能比別人的 <Score> 低.
此執行結果如下: (因為 Class_B 有兩位 100 分, 所以會查出兩筆資料)Class_A <Student><Name>Apple</Name><Score>100</Score></Student> Class_B <Student><Name>Peter</Name><Score>100</Score></Student> Class_B <Student><Name>Rex</Name><Score>100</Score></Student> Class_C <Student><Name>Tom</Name><Score>94</Score></Student>
- 相同的邏輯, 我們只要將 < 改成 >, > 改成 <, 就可以找出成績最差的資料:
XmlNodeList lstNode = doc.SelectNodes("//Class/Student[" + "position()!=../Student[position()] " + "and (Score < ../Student/Score and not(Score > ../Student/Score))]");
執行結果如下:Class_A <Student><Name>May</Name><Score>60</Score></Student> Class_B <Student><Name>Hebe</Name><Score>58</Score></Student> Class_C <Student><Name>Sam</Name><Score>66</Score></Student>
這時只要將查詢句中的 ../Student 改成 //Class/Student 就可以了. (參考如下)
- 找出成績最好的學生:
XmlNodeList lstNode = doc.SelectNodes("//Class/Student[" + "position()!=//Class/Student[position()] " + "and (Score > //Class/Student/Score and not(Score < //Class/Student/Score))]");
執行結果:Class_A <Student><Name>Apple</Name><Score>100</Score></Student> Class_B <Student><Name>Peter</Name><Score>100</Score></Student> Class_B <Student><Name>Rex</Name><Score>100</Score></Student>
- 找出成績最差的學生:
XmlNodeList lstNode = doc.SelectNodes("//Class/Student[" + "position()!=//Class/Student[position()] " + "and (Score < //Class/Student/Score and not(Score > //Class/Student/Score))]");
執行結果:Class_B <Student><Name>Hebe</Name><Score>58</Score></Student>
沒有留言:
張貼留言