پرس و جوی محتوای XML با XPath

XPath پیشنهاد رسمی W3C برای پرس و جو و جست و جو در محتوای XML است، در حقیقت XPath استانداری است که زبانی را در اختیار ما قرار می‌دهد که با استفاده از آن می‌توانیم المان‌ها و صفت‌ها مختلف یک فایلXML را مورد بررسی قرار دهیم.

XPath دارای ویژگی‌ها و امکانات زیر است:

Path Expression

Path Expression عبارت متنی است که به ما اجازه می‌دهد گره یا گره‌هایی را از داخل یک محتوای XML استخراج کنیم، جدول زیر عبارات مهم و کاربردی Path Expression را نشان می‌دهد.

عبارت عملکرد
node-name به کار بردن نام گره باعث می‌شود تا تمام گره‌های با نام مورد نظر انتخاب شوند.
/ مشخص می‌کند که انتخاب و جست و جو از ابتدای فایل صورت گیرد.
// تمام گره‌ها صرف نظر از مکان آن‌ها انتخاب می‌شوند.
. گره فعلی را انتخاب می‌کند.
.. پدر گره فعلی را انتخاب می‌کند.
@ برای انتخاب بر حسب صفت به کار می‌رود.

 

Predicates

پس از ساخت یک لیست توسط Path Expression با استفاده از Predicate می‌توانیم گره یا گره‌های خاصی را انتخاب می‌کنیم، Predicate با عبارت […] مشخص می‌شود که به جای … می‌توانیم از توابع استاندارد، اندیس یا عبارات پیچیده تر برای انتخاب گره‌های خاص استفاده کنیم، در ادامه با مثال با این موضوع آشنا می‌شویم:

عبارت عملکرد
/class/student[1] اولین گره student که زیر گره class باشد را انتخاب می‌کند.
/class/student[3] سومین گره student که زیر گره class باشد را انتخاب می‌کند.
/class/student[last()] آخرین گره student که زیر گره class باشد را انتخاب می‌کند.
/class/student[last()-1] گره ماقبل آخر را با شرایط قبلی انتخاب می‌کند.
//student[@sid=’333’] تمام گره‌های student که دارای sid برابر با 333 هستند را انتخاب می‌کند.
/class/student[position()<3] تمام گره‌های student زیر گره class که اندیس آن‌ها از 3 کمتر است را انتخاب می‌کند (یعنی دو گره ابتدایی انتخاب می‌شوند.)در اینجا اندیس از یک شروع می‌شود.

استفاده از XPath در جاوا:

خوشبختانه در جاوا با استفاده از کتابخانه‌های توکار می‌توانیم به سادگی از امکاناتXPath استفاده کنیم، به صورت کلی استفاده از XPath شامل مراحل زیر است:

  1. کتابخانه‌های مورد نیاز را import کنیم که معمولاً موارد زیر کافی هستند:
  2. import org.w3c.dom.*;
    import org.xml.sax.*;
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;
    import java.io.*;
    
  3. برای خواندن از فایل یک DocumentBuilder ایجاد کنیم:
  4. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    
  5. یک Document ایجاد کنیم و محتوای XML را از یک فایل یا استریم بخوانیم
  6. Document doc = builder.parse(input);
    
  7. یک شیء از کلاس XPath ایجاد کنیم:
  8. XPath xPath = XPathFactory.newInstance().newXPath();
    
  9. Path Expression مورد نظر را ساخته و آن را با متد compile کامپایل کنیم.
  10. XPathExpression expr = xPath.compile(XPATH_EXPRESSION_STRING);
    
  11. با استفاده از متد evaluate نتیجه مورد نظر را محاسبه کنیم .
  12. NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
    

در ادامه با استفاده از چند مثال به صورت عملی با موارد فوق آشنا می‌شویم. قبل از ادامه یک فایل XML به نام sample.xml ایجاد می‌کنیم و محتوای زیر را در آن می‌نویسیم و در درایو D ذخیره می‌کنیم:

<?xml version="1.0" encoding="utf-8" ?>
<Persons>
  <Person name="John Smith">
    <Age>30</Age>
    <Gender>Male</Gender>
  </Person>
  <Person name="Mike Folley">
    <Age>25</Age>
    <Gender>Male</Gender>
  </Person>
  <Person name="Lisa Carter">
    <Age>22</Age>
    <Gender>Female</Gender>
  </Person>
  <Person name="Jerry Frost">
    <Age>27</Age>
    <Gender>Male</Gender>
  </Person>
  <Person name="Adam Wong">
    <Age>35</Age>
    <Gender>Male</Gender>
  </Person>
</Persons>

برای انتخاب گره ای از فایل بالا که خاصیت Name آن برابری John Smith است به صورت زیر عمل می کنیم :

   1: import org.w3c.dom.*;
   2: import javax.xml.parsers.*;
   3: import javax.xml.xpath.*;
   4: import java.io.*;
   5: 
   6: public class XPathDemo 
   7: {
   8:     static void printNode(Node n) 
   9:     {
  10:         System.out.println("------");
  11:         Element e = (Element)n;
  12: 
  13:         //Parent Node
  14:         System.out.println(n.getNodeName() + " Name: " + e.getAttribute(" Name"));
  15: 
  16:         //Age	
  17:         String Age = e.getElementsByTagName("Age").item(0).getTextContent();
  18:         System.out.println("Person Age: " + Age);
  19: 
  20:         //Gender
  21:         String Gender = e.getElementsByTagName("Gender").item(0).getTextContent();
  22:         System.out.println("Person Gender: " + Gender);
  23:     }
  24: 
  25:     public static void main(String[] args) throws Exception 
  26:     {
  27: 
  28:         String XPATH_EXPRESSION_STRING = "//Person[@name='John Smith']";
  29: 
  30:         File myXMLFile = new File("D:/sample.xml");
  31: 
  32:         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
  33:         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
  34: 
  35:         Document doc = dBuilder.parse(myXMLFile);
  36: 
  37:         XPath xPath = XPathFactory.newInstance().newXPath();
  38:         XPathExpression expr = xPath.compile(XPATH_EXPRESSION_STRING);
  39: 
  40:         NodeList list = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
  41: 
  42:         int listSize = list.getLength();
  43:         System.out.println(listSize);
  44:         for (int i = 0; i < listSize; i++) 
  45:         {
  46:             Node nodeI = list.item(i);
  47:             printNode(nodeI);
  48:         }
  49:     }
  50: }
1
------
Person Name: John Smith
Person Age: 30
Person Gender: Male

برای انتخاب گره‌های از نوع Person که جنسیت (Gender) در آن‌ها زن (Female) باشد، کافی است که خط 28 کد بالا را به صورت زیر تغییر دهیم:

String XPATH_EXPRESSION_STRING ="//Person[Gender='Female']";
1
------
Person Name: Lisa Carter
Person Age: 22
Person Gender: Female

برای انتخاب گره‌های از نوع Person که سن (Age) آن‌ها بیشتر از 25 سال باشد، کافی است که خط 28 کد بالا را به صورت زیر تغییر دهیم:

String XPATH_EXPRESSION_STRING ="//Person[Age > 25]";
3
------
Person Name: John Smith
Person Age: 30
Person Gender: Male
------
Person Name: Jerry Frost
Person Age: 27
Person Gender: Male
------
Person Name: Adam Wong
Person Age: 35
Person Gender: Male