استفاده از XPath برای انتخاب گره ها

Xpath یک زبان پرس و جوی ویژه برای انتخاب گره‌ها در یک سند XML می‌باشد. با این زبان، لازم نیست که تمام ساختار درختی یک سند XML را جستجو کنید. در این درس ساختار پایه‌ای این زبان را فرا گرفته و آن را در برنامه به کار می‌بندید. دو متدی که در این زبان برای انتخاب گره‌ها مورد استفاده قرار می‌گیرند عبارتند از XmlNode.SelectNodes() و XmlNode.SelectSingleNode().
متد SelectNodes() یک XmlNodeList را برمی گرداند که شامل همه گره‌هایی است که با رشته Xpath مطابقت دارند. به سند XML زیر توجه کنید :

<?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>

فرض کنید که می‌خواهید سن هر شخص را به دست آورید، برای انکار می‌توانید از کد زیر استفاده نمایید :

XmlDocument document = new XmlDocument();
document.Load("Persons.xml");

XmlNodeList nodes = document.DocumentElement.SelectNodes("/Persons/Person/Age");

foreach(XmlNode node in nodes)
{
    textBoxResult.Text += node.InnerText + "rn";
}

در مثال بالا متد SelectNodes() یک آرگومان رشته‌ای قبول می‌کند که همان عبارت Xpath می‌باشد. مثلاً عبارت XPth در مثال بالا /Persons/Person/Age به ما می‌گوید که عنصر Age فرزند عنصر Person و عنصر Person خود نیز فرزند عنصر Persons می‌باشد. در نهایت همه گره‌های منطبق به صورت XmlList بر گشت داده می‌شوند. سپس از یک حلقه foreach برای چاپ هر سن در کنترل textBox استفاده کرده‌ایم.
در جدول زیر برخی از عملیاتی که می‌توان از آنها برای پرس و جو در گره‌ها استفاده کرد آمده است :

عبارت XPath توضیح
. گره جاری را انتخاب می‌کند.
.. گره پدر، گره جاری را انتخاب می‌کند.
* همه گره‌های فرزند گره جاری را انتخاب می‌کند.
nodename همه گره‌های فرزند با یک نام مشخص را انتخاب می‌کند.
/ گره ریشه را انتخاب می‌کند.
// گره‌هایی از گره جاری را بدون در نظر گرفتن مکان آنها انتخاب می‌کند.
//* همه عناصر داخل یک سند را انتخاب می‌کند.
/element یک عنصر ریشه با نام element انتخاب می‌کند. شروع مسیر با / به معنی استفاده از مسیر مطلق است.
/element/* همه فرزندهای عنصر ریشه را انتخاب می‌کند.
element/* همه عناصر فرزند یک عنصر فرزند را انتخاب می‌کند.
element/child عناصر فرزندی که فرزند یک عنصر فرزند خاص از گره جاری هستند را انتخاب می‌کند.
//element همه عناصر با یک نام خاص بدون در نظر گرفتن مکان آنها را انتخاب می‌کند.
element//child همه عناصر فرزند یک عنصر پدر را بدون در نظر گرفتن ماکن آن‌ها در داخل گره پدرانتخاب می‌کند.
@attribute یک صفت از گره جاری را انتخاب می‌کند.
//@attribute همه صفات با یک نام مشخص را بدون در نظر گرفتن مکان آنها در سند، انتخاب می‌کند.
@* همه صفات گره جاری را انتخاب می‌کند.
element[i] یک عنصر با یک نام و اندیش مشخص را انتخاب می‌کند.
text() متن همه گره‌های فرزند گره جاری را انتخاب می‌کند.
//text() متن همه عناصر داخل سند را انتخاب می‌کند.
//element/text() متن همه عناصر مورد نظر را انتخاب می‌کند.
//element[name=’value’] همه عناصری که دارای فرزندی با یک مقدار خاص هستند انتخاب می‌کند.
//element[@att=’value’] همه عناصری با یک صفت مشخص با مقدار مشخصی هستند را انتخاب می‌کند.

به عنوان مثال برای انتخاب گره جاری از عملگر (.) استفاده می‌شود :

XmlNode current = document.DocumentElement.SelectSingleNode(".");

به این نکته توجه کنید که متد XmlNode.SelectSingleNode() فقط یک گره را انتخاب می‌کند و در صورتیکه چندین نتیجه وجود داشته باشد فقط اولین گره منطبق را بر می‌گرداند. برای انتخاب همه عناصر Person که فرزند گره Persons هستند، می‌توانید از عبارت Xpath زیر استفاده کنید :

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("/Persons/Person");

به این نکته توجه نمایید که شروع عبارت با علامت اسلش (/) به معنای این است که می‌خواهید از مسیر مطلق، استفاده کنید. با گره ریشه (Persons) شروع کرده‌ایم و سپس به دنبال گره‌های Person که مستقیماً گره فرزند آن هستند می‌گردیم. برای به دست آوردن سن هر فرد از عبارت زیر استفاده می‌کنیم :

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("/Persons/Person/Age");

می‌توان از آدرس دهی نسبی هم به شرطی که جستجو از گره جاری شروع شود استفاده کرد. به عنوان مثال می‌توان همه گره‌های فرزند گره ریشه DocumentElement را با استفاده از کد زیر به دست آورد :

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("Person");

یا سن هر شخص را به وسیله کد زیر:

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("Person/Age");

همانطور که مشاهده می‌کنید در آدرس دهی نسبی از علامت / استفاده نمی‌کنیم. می‌توانید پرس و جوی گره‌ها را بدون در نظر گرفتن مکان آنها در سند انجام داد. این کار زمانی مفید است، که نخواهید همه سند را برای یافتن گره‌هایی که با گره مورد نظر شما انطباق دارند جستجو کنید. به عنوان مثال اگر بخواهید همه گره‌های جنسیت (Gender) را بدست اورید می‌توانید از کد زیر استفاده نمایید:

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("//Gender");

قرار گرفتن علامت / قبل از نام عنصر بدین معناست که باید همه سند مورد جستجو قرار گیرد. عبارت پرس و جو تمام گره‌های منطبق با عبارت مورد نظر را در هر جای سند بر می‌گرداند. اگر بخواهید منطقه محدودی از سند را جستجو کنید می‌توانید گره پدر یا ریشه گره‌ای که قرار است جستجو در آن انجام شود، مشخص کنید:

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("/Persons//Gender");

کد بالا همه عناصر Genderکه در داخل گره Person قرار دارند را جستجو می‌کند.
برای یافتن یک گره خاص می‌توانید از اندیس آن استفاده کنید. کد زیر سومین فرزند عنصر Person را برگشت می‌دهد :

XmlNode personNodes = 
   document.DocumentElement.SelectSingleNode("/Persons/Person[3]");

در کد بالا از آنجاییکه به دنبال یک گره ساده هستیم از متد SelectSingleNode() استفاده کرده‌ایم. سومین عنصر Person به وسیله Person[3] نمایش داده می‌شود به همین منظور ما از اندیس 3 استفاده کرده‌ایم. اندیس در XML بر خلاف آرایه‌ها از یک شروع می‌شود نه صفر. برای انتخاب همه افرادی که جنس مذکر هستند می‌توانید از کد زیر استفاده کنید :

XmlNodeList personNodes = 
   document.DocumentElement.SelectNodes("//Person[Gender='Male']");

از آنجاییکه از علامت // استفاده کرده‌ایم تمام سند مورد جستجو قرار می‌گیرد. در داخل کروشه هم نام عنصر فرزند و مقدار مخصوص آن را نوشته‌ایم. مقدار عنصر اگر از نوع رشته باشد باید در داخل کوتیشن قرار داده شود. هنگام کار با صفات یک عنصر می‌توانید از علامت @ قبل از نام صفت استفاده کنید. به عنوان مثال کد زیر اسامی همه افراد را چاپ می‌کند:

XmlNodeList list = document.DocumentElement.SelectNodes(@"//Person/@name");

foreach (XmlNode node in list)
{
    textBox1.Text += node.Value + "rn";
}

XPath مبحث بزرگی است. فقط برخی از اجزای پایه‌ای آن در این درس را بررسی کردیم. برای یادگیری مطالب بیشتر به آدرس زیر مراجعه کنید :