首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET XML 資料處理實戰:DataSet 與 LINQ to XML 雙引擎操作指南

     編輯:ASP.NET 基礎

XML 在 ASP.NET 定位

XML(可延伸標記語言)是**結構化資料交換與儲存**的通用格式。ASP.NET 提供兩大原生引擎處理 XML:

  • DataSet:關聯式思維,適合「XML ↔ 資料表」雙向轉換、DataGrid/GridView 直接綁定。
  • LINQ to XML (System.Xml.Linq):函數式建構/查詢/轉換,語法優雅、效能優異、支援串流處理大型 XML。

一、範例資料:課程目錄 (Courses.xml)

<?xml version="1.0" encoding="utf-8"?>
<Courses>
  <Course Id="1" Category="Development">
    <Title>ASP.NET Core 實戰</Title>
    <Author>張三</Author>
    <Price>1200</Price>
    <Tags><Tag>C#</Tag><Tag>Web</Tag></Tags>
  </Course>
  <Course Id="2" Category="Cloud">
    <Title>Azure 雲端架構</Title>
    <Author>李四</Author>
    <Price>1500</Price>
    <Tags><Tag>Azure</Tag><Tag>DevOps</Tag></Tags>
  </Course>
</Courses>

二、DataSet 引擎:零程式碼綁定 GridView

2.1 讀取 XML → DataTable → GridView

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var ds = new DataSet();
        ds.ReadXml(Server.MapPath("~/App_Data/Courses.xml")); // 自動推斷 Schema
        
        // DataSet 可能產生多個 DataTable (巢狀元素會拆成關聯表)
        // 主表通常是第一個
        gvCourses.DataSource = ds.Tables[0].DefaultView;
        gvCourses.DataBind();
    }
}

2.2 寫入 DataTable → XML (支援 Schema)

public void SaveCourses(DataTable dt)
{
    var ds = new DataSet();
    ds.Tables.Add(dt.Copy());
    ds.WriteXml(Server.MapPath("~/App_Data/Courses.xml"), XmlWriteMode.WriteSchema); // 含結構描述
}

2.3 進階:手動定義 Schema 強型別化

var ds = new DataSet();
ds.ReadXmlSchema(Server.MapPath("~/App_Data/Courses.xsd")); // 先載入 XSD
ds.ReadXml(Server.MapPath("~/App_Data/Courses.xml"));       // 再載入資料
// 此時 ds.Tables["Course"].Columns["Price"].DataType == typeof(decimal)

三、LINQ to XML 引擎:現代函數式操作

3.1 載入與基本查詢

XDocument doc = XDocument.Load(Server.MapPath("~/App_Data/Courses.xml"));

// 查詢所有開發類課程標題
var devTitles = doc.Descendants("Course")
    .Where(c => (string)c.Attribute("Category") == "Development")
    .Select(c => (string)c.Element("Title"));

// 輸出: ASP.NET Core 實戰
foreach (var t in devTitles) Console.WriteLine(t);

3.2 建構新 XML 文件 (函數式建構)

var newDoc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("Courses",
        from c in GetCourseDtos()
        select new XElement("Course",
            new XAttribute("Id", c.Id),
            new XAttribute("Category", c.Category),
            new XElement("Title", c.Title),
            new XElement("Author", c.Author),
            new XElement("Price", c.Price),
            new XElement("Tags",
                from tag in c.Tags select new XElement("Tag", tag))
        )
    )
);
newDoc.Save(Server.MapPath("~/App_Data/NewCourses.xml"));

3.3 修改現有 XML (就地更新)

var doc = XDocument.Load(path);
var course = doc.Descendants("Course").FirstOrDefault(c => (int)c.Attribute("Id") == 1);
if (course != null)
{
    course.Element("Price").SetValue(1300); // 修改價格
    course.Element("Tags").Add(new XElement("Tag", "MVC")); // 新增標籤
    doc.Save(path);
}

3.4 大型 XML 串流處理 (XmlReader + LINQ)

// 僅讀取 Course 元素,不將整份文件載入記憶體
using (var reader = XmlReader.Create(Server.MapPath("~/App_Data/HugeCourses.xml")))
{
    reader.MoveToContent();
    while (reader.Read())
    {
        if (reader.NodeType == XmlNodeType.Element && reader.Name == "Course")
        {
            var courseElement = XElement.ReadFrom(reader) as XElement;
            var price = (int)courseElement.Element("Price");
            if (price > 1000)
                ProcessExpensiveCourse(courseElement);
        }
    }
}

四、XML Schema (XSD) 驗證:確保資料完整性

var schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(Server.MapPath("~/App_Data/Courses.xsd")));

var doc = XDocument.Load(Server.MapPath("~/App_Data/Courses.xml"));
bool isValid = true;
doc.Validate(schemas, (o, e) => 
{
    _logger.Error($"XML 驗證失敗: {e.Message}");
    isValid = false;
});

if (isValid) ProcessValidDocument(doc);

五、XML 序列化:物件圖 ↔ XML 雙向轉換

5.1 XmlSerializer (傳統、屬性導向)

[XmlRoot("Course")]
public class CourseDto
{
    [XmlAttribute("Id")] public int Id { get; set; }
    [XmlAttribute("Category")] public string Category { get; set; }
    [XmlElement("Title")] public string Title { get; set; }
    [XmlElement("Author")] public string Author { get; set; }
    [XmlElement("Price")] public decimal Price { get; set; }
    [XmlArray("Tags")] [XmlArrayItem("Tag")] public List Tags { get; set; }
}

// 序列化
var serializer = new XmlSerializer(typeof(List), new XmlRootAttribute("Courses"));
using (var writer = XmlWriter.Create(path, new XmlWriterSettings { Indent = true }))
    serializer.Serialize(writer, courses);

// 反序列化
List courses;
using (var reader = XmlReader.Create(path))
    courses = (List)serializer.Deserialize(reader);

5.2 DataContractSerializer (WCF/現代、契約導向)

[DataContract(Namespace = "")]
public class CourseDto
{
    [DataMember(Order = 1)] public int Id { get; set; }
    [DataMember(Order = 2)] public string Title { get; set; }
    // ...
}

// 二進制/XML/JSON 通用
var serializer = new DataContractSerializer(typeof(List));
using (var ms = new MemoryStream())
{
    serializer.WriteObject(ms, courses); // 預設 XML
    // serializer.WriteObject(ms, courses, new DataContractJsonSerializerSettings()); // JSON
}

六、效能與選型決策表

場景推薦引擎理由
小型 XML (< 1MB) 直接綁定 GridView/RepeaterDataSet零程式碼、自動 Schema 推斷、雙向綁定
複雜查詢、轉換、建構、大型 XML (> 10MB)LINQ to XML串流支援、函數式語法、記憶體效率高
Web Service 回傳 / 設定檔 / 物件持久化XmlSerializer / DataContractSerializer強型別、版本容忍、契約優先
需 XSD 驗證LINQ to XML + Validate()標準化驗證、錯誤報告豐富

七、常見陷阱

  • 命名空間:XElement 查詢需包含命名空間 XNamespace ns = "..."; doc.Descendants(ns + "Course")。
  • 編碼不一致:儲存時指定 Encoding.UTF8,避免中文亂碼。
  • DataSet 推斷 Schema 不準:巢狀元素會拆成多表關聯,建議先載入 XSD。
  • 大檔案載入 OOM:務必使用 XmlReader 串流模式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved