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

ASP.NET XML 文件操作完整指南:XPath 查詢、節點增刪改、資料綁定與效能優化

     編輯:ASP.NET 基礎

XML 基礎概念速覽

節點類型範例說明
Element<book>...</book>標籤配對構成的元素
Attributeid="10001"元素屬性
Text<name>書名</name> 中的「書名」元素內文字內容
Comment<!-- 備註 -->註解節點

範例 XML 結構

<?xml version="1.0" encoding="UTF-8"?>
<library>
  <books id="計算機類">
    <book id="10001">
      <name>書名1</name>
      <publish>出版社1</publish>
      <price>價格1</price>
    </book>
    <book id="10001">...</book>
  </books>
  <books id="人文類">...</books>
</library>

核心操作:XmlDocument + XPath


var xdoc = new XmlDocument();
xdoc.Load(Server.MapPath("~/App_Data/books.xml"));

// 1. 精確定位單一節點 (最常用)
string xpath = "//books[@id='計算機類']//book[@id='10001']";
XmlNode node = xdoc.DocumentElement.SelectSingleNode(xpath);

// 2. 取得子節點集合
XmlNodeList children = node.ChildNodes;
foreach (XmlNode child in children)
{
    Console.WriteLine($"{child.Name}: {child.InnerText}");
}

// 3. 取得屬性值
string bookId = node.Attributes["id"]?.Value;

// 4. 多條件 / 聯集查詢
// 聯集:兩個路徑合併
xpath = "//books[@id='計算機類']//book[@id='10001'] | //books[@id='人文類']//book[@id='20001']";

// 通配符:所有子孫 name 節點
xpath = "//books[@id='計算機類']//*/name";

// 文字節點直接取值
xpath = "//books[@id='計算機類']//book[@id='10001']//name/text()";
string name = xdoc.DocumentElement.SelectSingleNode(xpath)?.Value;

XPath 語法速查表

語法含義範例
//任意深度子孫//book 所有 book 節點
/直接子代/library/books
[@attr='val']屬性過濾//book[@id='10001']
text()文字節點//name/text()
*任意元素//books/* 所有 books 直系子元素
|聯集//a | //b
[position()=1]第一個//book[1]
[last()]最後一個//book[last()]
contains()包含文字//book[contains(name, 'C#')]

XML 編輯操作:增刪改


// 建立輔助方法簡化操作
public static class XmlHelper
{
    public static XmlAttribute CreateAttr(this XmlDocument doc, string name, string value)
    {
        var attr = doc.CreateAttribute(name);
        attr.Value = value;
        return attr;
    }

    public static XmlElement CreateElem(this XmlDocument doc, string name, string innerText = null)
    {
        var elem = doc.CreateElement(name);
        if (innerText != null) elem.InnerText = innerText;
        return elem;
    }
}

// 1. 新增屬性
XmlNode book = xdoc.SelectSingleNode("//book[@id='10001']");
book.Attributes.Append(xdoc.CreateAttr("isbn", "978-7-121-12345-6"));

// 2. 刪除屬性
book.Attributes.RemoveNamedNode("isbn");

// 3. 新增子元素
XmlElement newBook = xdoc.CreateElem("book");
newBook.Attributes.Append(xdoc.CreateAttr("id", "10003"));
newBook.AppendChild(xdoc.CreateElem("name", "新書名"));
newBook.AppendChild(xdoc.CreateElem("publish", "新出版社"));
newBook.AppendChild(xdoc.CreateElem("price", "99.9"));
xdoc.SelectSingleNode("//books[@id='計算機類']").AppendChild(newBook);

// 4. 刪除子元素
XmlNode oldBook = xdoc.SelectSingleNode("//book[@id='10001']");
oldBook.ParentNode.RemoveChild(oldBook);

// 5. 替換子元素
XmlNode newNode = xdoc.CreateElem("book");
newNode.Attributes.Append(xdoc.CreateAttr("id", "10001"));
// ...填充內容
oldBook.ParentNode.ReplaceChild(newNode, oldBook);

// 6. 修改文字內容
XmlNode priceNode = xdoc.SelectSingleNode("//book[@id='10001']/price");
priceNode.InnerText = "88.8";

// 7. 儲存變更
xdoc.Save(Server.MapPath("~/App_Data/books.xml"));

資料綁定:XML 繫結到 GridView/Repeater


// 方法一:XmlDataSource 控制項 (宣告式)
<asp:XmlDataSource ID="XmlDS" runat="server" 
    DataFile="~/App_Data/books.xml" 
    XPath="//books[@id='計算機類']//book" />
<asp:GridView ID="gvBooks" runat="server" DataSourceID="XmlDS" AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField DataField="id" HeaderText="ID" ReadOnly="True" />
        <asp:BoundField DataField="name" HeaderText="書名" />
        <asp:BoundField DataField="price" HeaderText="價格" />
    </Columns>
</asp:GridView>

// 方法二:程式碼後置 DataTable 轉換 (靈活性高)
public DataTable XmlToDataTable(string xmlPath, string xpath)
{
    var dt = new DataTable();
    dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Price");
    
    var doc = new XmlDocument();
    doc.Load(xmlPath);
    var nodes = doc.SelectNodes(xpath);
    
    foreach (XmlNode node in nodes)
    {
        var row = dt.NewRow();
        row["Id"] = node.Attributes["id"]?.Value;
        row["Name"] = node.SelectSingleNode("name")?.InnerText;
        row["Price"] = node.SelectSingleNode("price")?.InnerText;
        dt.Rows.Add(row);
    }
    return dt;
}

// 使用
gvBooks.DataSource = XmlToDataTable(Server.MapPath("~/books.xml"), "//book");
gvBooks.DataBind();

效能優化:大型 XML 處理策略

場景問題解決方案
XML > 10MBXmlDocument 全載入記憶體使用 XmlReader 流式讀取 (前向唯讀、低記憶體)
頻繁查詢重複 Load/Parse快取 XmlDocument (MemoryCache + 檔案監視失效)
複雜 XPathSelectNodes 效能差預先建立 索引字典 (ID → 節點引用)
寫入頻繁Save 重寫整個檔案改用 SQLite/資料庫,XML 僅作匯出格式

XmlReader 流式讀取範例


public IEnumerable StreamBooks(string xmlPath)
{
    using (var reader = XmlReader.Create(xmlPath))
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element && reader.Name == "book")
            {
                string id = reader.GetAttribute("id");
                reader.ReadToDescendant("name");
                string name = reader.ReadElementContentAsString();
                reader.ReadToNextSibling("publish");
                string publish = reader.ReadElementContentAsString();
                reader.ReadToNextSibling("price");
                string price = reader.ReadElementContentAsString();
                
                yield return new Book { Id = id, Name = name, Publish = publish, Price = price };
            }
        }
    }
}

現代化替代:LINQ to XML (System.Xml.Linq)


using System.Xml.Linq;

var xdoc = XDocument.Load(path);

// 查詢
var books = xdoc.Descendants("book")
    .Where(b => b.Attribute("id")?.Value == "10001")
    .Select(b => new {
        Id = b.Attribute("id").Value,
        Name = b.Element("name")?.Value,
        Price = b.Element("price")?.Value
    });

// 建立/修改
var newBook = new XElement("book",
    new XAttribute("id", "10003"),
    new XElement("name", "LINQ to XML 實戰"),
    new XElement("price", "120")
);
xdoc.Root.Element("books").Add(newBook);
xdoc.Save(path);

總結

ASP.NET XML 操作核心在於 XmlDocument + XPath 的組合:SelectSingleNode/SelectNodes 精確定位、屬性/文字節點分離存取、編輯後 Save 持久化。大型/高頻場景必須轉向 XmlReader 流式處理、快取策略、或改用資料庫。新專案強烈建議採用 LINQ to XML (XDocument),語法更現代、型別安全、支援 LINQ 查詢、功能更完整 (命名空間、註解保留、序列化整合)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved