ใน .NET การอ่านข้อมูลแบบ XML จาก Data source ต่างๆ เช่น RSS Feed หรือจาก Google Alert มักจะสามารถทำได้โดยการใช้ System.Xml.Linq
เช่นการอ่านข้อมูลจากไฟล์ XML จาก server
using System.Xml.Linq;
string rssUrl = "https://nextflow.in.th/data.xml";
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync(rssUrl);
string rssData = await response.Content.ReadAsStringAsync();
ซึ่งผลลัพธ์จะได้เป็นข้อความ XML ดิบๆ มา
เราสามารถทำงานกับข้อความ XML String ดิบๆ นี้ง่ายขึ้นโดยใช้ XDocument
class ทำการแปลงข้อมูล XML String ให้อยู่ในรูปแบบ instance ที่เรียกใช้ method ทำงานด้วยง่ายกว่าได้
XDocument rssDoc = XDocument.Parse(rssData);
แต่ที่สำคัญคือ ตอนที่เราใช้คำสั่ง .Descendants()
ในการดึงเอา XML Element ที่ต้องการออกมา
ถ้าเกิด XML Document ที่เราได้มา มีการกำหนด namespace (xmlns) เอาไว้ ต้องระบุ namespace ลงไปด้วย
เช่น RSS ของ Google Alert จะมีแบบด้านล่าง
<feed xmlns="http://www.w3.org/2005/Atom" ...>
แล้วถ้าเราต้องการดึง <entry>
ออกมาก็ต้องมีการประกาศ XML namespace เพื่อใช้ในการ query แบบด้านล่าง
XDocument rssDoc = XDocument.Parse(rssData);
// สร้าง XML namespace instance
XNamespace ns = "http://www.w3.org/2005/Atom";
// ใช้ namespace ในการ query 'entry' element
var entries = rssDoc.Descendants(ns + "entry");
มิฉะนั้น query มายังไง ใช้ LINQ หรือไม่ ก็จะได้แค่ List เปล่าๆ มาครับ
แถมด้านล่าง จะเห็นว่าในการดึง Attribute และ Nested-element ที่ซ้อนอยู่ด้านในก็จะต้องใช้ XML namespace ควบคู่เช่นกัน
XDocument rssDoc = XDocument.Parse(rssData);
// สร้าง XML namespace instance
XNamespace ns = "http://www.w3.org/2005/Atom";
// ประกาศสร้าง Class RssEntry
public class RssEntry
{
public string? Title { get; set; }
public string? Link { get; set; }
public DateTime? PubDate { get; set; }
public string? Description { get; set; }
}
// ใช้ namespace ในการ query 'entry' element รวมถึง element ที่อยู่ด้านใน
var entries = from item in rssDoc.Descendants(ns + "entry")
select new RssEntry
{
// ดึงค่า Nested-element ชื่อ title, link, published จาก entry element มาก็ต้องใช้ namespace นะ
Title = (string)item.Element(ns + "title"),
// ในส่วนของ attribute value ไม่ต้องใส่ namespace ครับ
Link = (string)item.Element(ns + "link").Attribute("href"),
PubDate = DateTime.Parse((string)item.Element(ns + "published")),
Description = (string)item.Element(ns + "content")
};
อ้างอิง – StackOverflow