Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 11 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
11
Dung lượng
208,67 KB
Nội dung
Dưới đây là cách sử dụng lớp này để xác nhận tính hợp lệ của danh mục sản phẩm:
using System;
public class ValidateXml {
private static void Main() {
ConsoleValidator consoleValidator = new ConsoleValidator();
Console.WriteLine("Validating ProductCatalog.xml.");
bool success = consoleValidator.ValidateXml("ProductCatalog.xml",
"ProductCatalog.xsd");
if (!success) {
Console.WriteLine("Validation failed.");
}else {
Console.WriteLine("Validation succeeded.");
}
Console.ReadLine();
}
}
Nếu tàiliệu hợp lệ thì sẽ không có thông báo nào xuất hiện, và biến success sẽ được thiết
lập thành true. Nhưng xét xem điều gì sẽ xảy ra nếu bạn sử dụng một tàiliệu phá vỡ các
quy tắc Schema, chẳng hạn file ProductCatalog_Invalid.xml như sau:
<?xml version="1.0" ?>
<productCatalog>
<catalogName>Acme Fall 2003 Catalog</catalogName>
<expiryDate>Jan 1, 2004</expiryDate>
<products>
<product id="1001">
<productName>Magic Ring</productName>
<productPrice>$342.10</productPrice>
<inStock>true</inStock>
</product>
<product id="1002">
<productName>Flying Carpet</productName>
<productPrice>982.99</productPrice>
<inStock>Yes</inStock>
</product>
</products>
</productCatalog>
Nếu bạn kiểm tra tàiliệu này, biến success sẽ được thiết lập thành false và kết xuất sẽ cho
biết các lỗi:
Validating ProductCatalog_Invalid.xml.
Validation error: The 'expiryDate' element has an invalid value according to its data
type. An error occurred at file:///I:/CSharp/Chuong05/05-08/
bin/Debug/ProductCatalog_Invalid.xml, (4, 30).
Validation error: The 'productPrice' element has an invalid value according to its data
type. An error occurred at file:///I:/CSharp/Chuong05/05-08/
bin/Debug/ProductCatalog_Invalid.xml, (9, 36).
Validation error: The 'inStock' element has an invalid value according to its data
type. An error occurred at file:///I:/CSharp/Chuong05/05-08/
bin/Debug/ProductCatalog_Invalid.xml, (15, 27).
Validation failed.
Cuối cùng, nếu muốn xác nhận tính hợp lệ của một tàiliệuXML và rồi xử lý nó, bạn có
thể sử dụng XmlValidatingReader để quét tàiliệu khi nó được đọc vào một
XmlDocument trong-bộ-nhớ:
XmlDocument doc = new XmlDocument();
XmlTextReader r = new XmlTextReader("ProductCatalog.xml");
XmlValidatingReader validator = new XmlValidatingReader(r);
// Nạp Schema vào validator.
validator.ValidationType = ValidationType.Schema;
XmlSchemaCollection schemas = new XmlSchemaCollection();
schemas.Add(null, "ProductCatalog.xsd");
validator.Schemas.Add(schemas);
// Nạp và kiểm tra tàiliệu cùng một lúc.
try {
doc.Load(validator);
// (Validation thành công.)
}catch (XmlSchemaException err) {
// (Validation thất bại.)
}
1.1 Sử dụng XML Serialization với các đối tượng tùy biến
V
V
Bạn cần sử dụng XML như một định dạng tuần tự hóa (serialization format).
Tuy nhiên, bạn không muốn xử lý XML trực tiếp trong mã lệnh, mà muốn
tương tác với dữ liệu bằng các đối tượng tùy biến.
#
#
Sử dụng lớp System.Xml.Serialization.XmlSerializer để chuyển dữ liệu từ đối
tượng của bạn sang XML, và ngược lại. Bạn cũng có thể đánh dấu mã lệnh của
lớp bằng các đặc tính để tùy biến biểu diễn XML của nó.
Lớp XmlSerializer cho phép chuyển các đối tượng thành dữ liệu XML, và ngược lại. Lớp
này đủ thông minh để tạo đúng các mảng khi nó tìm thấy các phần t
ử lồng bên trong.
Các yêu cầu khi sử dụng XmlSerializer:
• XmlSerializer chỉ tuần tự hóa các thuộc tính và các biến công khai.
• Các lớp cần tuần tự hóa phải chứa một phương thức khởi dựng mặc định không có
đối số. XmlSerializer sẽ sử dụng phương thức khởi dựng này khi tạo đối tượng mới
trong quá trình giải tuần tự hóa.
• Các thuộc tính của lớp phải là khả-đọc (
readable) và khả-ghi (writable). Đó là vì
XmlSerializer sử dụng hàm truy xuất thuộc tính get để lấy thông tin và hàm truy
xuất thuộc tính set để phục hồi dữ liệu sau khi giải tuần tự hóa.
# Bạn cũng có thể lưu trữ các đối tượng theo định dạng dựa-trên-XML bằng cách
sử dụng .NET Serialization và System.Runtime.Serialization.Formatters.Soap.
SoapFormatter. Trong trường hợp này, bạn chỉ cần làm cho lớp của bạn trở
thành khả-tuần-tự-hóa, không cần cung cấp phương thức khởi dựng mặc định
hay bảo đảm tất cả các thuộc tính là khả ghi. Tuy nhiên, cách này không cho
bạn quyền kiểm soát trên định dạng XML
đã-được-tuần-tự-hóa.
Để sử dụng XML serialization, trước hết bạn phải đánh dấu các đối tượng dữ liệu với các
đặc tính cho biết phép ánh xạ sang XML. Các đặc tính này thuộc không gian tên
System.Xml.Serialization và bao gồm:
• XmlRoot—cho biết tên phần tử gốc của file XML. Theo mặc định, XmlSerializer sẽ
sử dụng tên của lớp. Đặc tính này có thể được áp dụng khi khai báo lớp.
• XmlElement—cho biết tên phần tử
dùng cho một thuộc tính hay biến công khai.
Theo mặc định, XmlSerializer sẽ sử dụng tên của thuộc tính hay biến công khai.
• XmlAttribute—cho biết một thuộc tính hay biến công khai sẽ được tuần tự hóa
thành một đặc tính (không phải phần tử), và chỉ định tên đặc tính.
• XmlEnum—cấu hình phần text sẽ được sử dụng khi tuần tự hóa các giá trị liệt kê.
Nếu bạn không sử dụng XmlEnum, tên của hằng liệt kê sẽ được sử dụng.
• XmlIgnore—cho biết một thuộc tính hay biến công khai sẽ không được tuần tự hóa.
Ví dụ, xét danh mục sản phẩm đã được trình bày trong mục 5.1. Bạn có thể mô tả tàiliệu
XML này bằng các đối tượng ProductCatalog và Product như sau:
using System;
using System.Xml.Serialization;
[XmlRoot("productCatalog")]
public class ProductCatalog {
[XmlElement("catalogName")]
public string CatalogName;
// Sử dụng kiểu dữ liệu ngày (bỏ qua phần giờ).
[XmlElement(ElementName="expiryDate", DataType="date")]
public DateTime ExpiryDate;
// Cấu hình tên thẻ.
[XmlArray("products")]
[XmlArrayItem("product")]
public Product[] Products;
public ProductCatalog() {
// Phương thức khởi dựng mặc định (dùng khi giải tuần tự hóa).
}
public ProductCatalog(string catalogName, DateTime expiryDate) {
this.CatalogName = catalogName;
this.ExpiryDate = expiryDate;
}
}
public class Product {
[XmlElement("productName")]
public string ProductName;
[XmlElement("productPrice")]
public decimal ProductPrice;
[XmlElement("inStock")]
public bool InStock;
[XmlAttributeAttribute(AttributeName="id", DataType="integer")]
public string Id;
public Product() {
// Phương thức khởi dựng mặc định (dùng khi giải tuần tự hóa).
}
public Product(string productName, decimal productPrice) {
this.ProductName = productName;
this.ProductPrice = productPrice;
}
}
Chú ý rằng, các lớp này sử dụng các đặc tính XML Serialization để đổi tên phần tử (sử
dụng kiểu ký hiệu Pascal
1[1][1]
trong tên thành viên lớp, và kiểu ký hiệu lưng lạc đà
2[2][2]
trong tên thẻ XML), cho biết các kiểu dữ liệu không rõ ràng, và chỉ định các phần tử
<product> sẽ được lồng bên trong <productCatalog> như thế nào.
Bằng cách sử dụng các lớp tùy biến này và đối tượng XmlSerializer, bạn có thể chuyển
XML thành các đối tượng và ngược lại. Đoạn mã dưới đây tạo một đối tượng
ProductCatalog mới, tuần tự hóa đối tượng thành tàiliệu XML, giải tuần tự hóa tài li
ệu
thành đối tượng, và rồi hiển thị tàiliệu này:
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
public class SerializeXml {
private static void Main() {
// Tạo danh mục sản phẩm.
ProductCatalog catalog = new ProductCatalog("New Catalog",
DateTime.Now.AddYears(1));
Product[] products = new Product[2];
products[0] = new Product("Product 1", 42.99m);
products[1] = new Product("Product 2", 202.99m);
catalog.Products = products;
// Tuần tự hóa danh mục ra file.
XmlSerializer serializer =
new XmlSerializer(typeof(ProductCatalog));
FileStream fs =
new FileStream("ProductCatalog.xml", FileMode.Create);
serializer.Serialize(fs, catalog);
fs.Close();
catalog = null;
// Giải tuần tự hóa danh mục từ file.
fs = new FileStream("ProductCatalog.xml", FileMode.Open);
catalog = (ProductCatalog)serializer.Deserialize(fs);
// Tuần tự hóa danh mục ra cửa sổ Console.
serializer.Serialize(Console.Out, catalog);
Console.ReadLine();
}
}
1.2 Tạo XML Schema cho một lớp .NET
V
V
Bạn cần tạo một XML Schema dựa trên một hay nhiều lớp C#. Điều này cho
phép bạn kiểm tra tính hợp lệ của các tàiliệuXML trước khi giải tuần tự hóa
chúng với XmlSerializer.
#
#
Sử dụng tiện ích dòng lệnh XML Schema Definition Tool (xsd.exe—đi kèm với
.NET Framework). Chỉ định tên của assembly làm đối số dòng lệnh, và thêm đối
số /t:[TypeName] để cho biết kiểu cần chuyển đổi.
Mục 5.9 đã trình bày cách sử dụng XmlSerializer để tuần tự hóa đối tượng .NET thành
XML, và giải tuần tự hóa XML thành đối tượng .NET. Nhưng nếu muốn sử dụng XML
như
một phương cách để tương tác với các ứng dụng khác, quy trình nghiệp vụ, hay các
ứng dụng phi-Framework, bạn sẽ cần xác nhận tính hợp lệ của XML trước khi giải tuần tự
hóa nó. Bạn cũng sẽ cần tạo một tàiliệuXML Schema định nghĩa cấu trúc và các kiểu dữ
liệu được sử dụng trong định dạng XML của bạn, để các ứng dụng khác có thể làm việc
với nó. Một giải pháp là sử dụng tiện ích dòng lệnh xsd.exe
.
Tiện ích xsd.exe đi kèm với .NET Framework. Nếu đã cài đặt Microsoft Visual Studio
.NET, bạn sẽ tìm thấy nó trong thư mục C:\Program Files\Microsoft Visual Studio
.NET\FrameworkSDK\Bin. Tiện ích xsd.exe có thể tạo ra XML Schema từ một assembly
đã được biên dịch. Bạn chỉ cần cung cấp tên file và cho biết lớp mô tả tàiliệuXML với
đối số /t:[TypeName].
Ví dụ, xét các lớp ProductCatalog và Product đã được trình bày trong mục 5.9. Bạn có
thể tạo
XML Schema cho một danh mục sản phẩm với dòng lệnh sau:
xsd 05-09.exe /t:ProductCatalog
Bạn chỉ cần chỉ định lớp ProductCatalog trên dòng lệnh, vì lớp này mô tả tàiliệu XML.
XML Schema được tạo ra trong ví dụ này (có tên mặc định là schema0.xsd) sẽ mô tả đầy
đủ một danh mục sản phẩm, với các item sản phẩm lồng bên trong. Bây giờ, bạn có thể
sử dụng XmlValidatingReader (đã được trình bày trong mục 5.8) để kiểm tra tính hợp lệ
của tàiliệuXML dựa vào XML Schema này.
1.3 Tạo lớp từ một XML Schema
V
V
Bạn cần tạo một hay nhiều lớp C# dựa trên một XML Schema; để sau đó, bạn
có thể tạo một tàiliệuXML theo định dạng phù hợp bằng các đối tượng này và
XmlSerializer.
#
#
Sử dụng tiện ích dòng lệnh xsd.exe (đi kèm với .NET Framework). Chỉ định tên
file Schema làm đối số dòng lệnh, và thêm đối số /c để cho biết bạn muốn tạo
mã lệnh cho lớp.
Mục 5.10 đã giới thiệu tiện ích dòng lệnh xsd.exe, tiện ích này có thể được sử dụng để tạo
XML Schema dựa trên định nghĩa lớp. Quá trình ngược lại (tạo mã lệnh C# dựa trên mộ
t
tài liệuXML Schema) cũng có thể xảy ra. Việc này hữu ích khi bạn muốn ghi một định
dạng XML nào đó, nhưng lại không muốn tạo tàiliệu này bằng cách ghi từng nút một với
lớp XmlDocument hay XmlTextWriter. Thay vào đó, bằng cách sử dụng xsd.exe, bạn có
thể tạo ra một tập đầy đủ các đối tượng .NET. Kế đó, bạn có thể tuần tự hóa các đối tượng
này thành biể
u diễn XML bằng XmlSerializer, như được mô tả trong mục 5.9.
Để tạo mã lệnh từ một XML Schema, bạn chỉ cần cung cấp tên file Schema và thêm đối số
/c để cho biết bạn muốn tạo ra lớp. Ví dụ, xét XML Schema đã được trình bày trong mục
5.8. Bạn có thể tạo mã lệnh C# từ Schema này với dòng lệnh sau:
xsd ProductCatalog.xsd /c
Lệnh này sẽ tạo ra một file (ProductCatalog.cs) gồm hai lớp: Product và productCalalog.
Hai lớp này tương tự với hai lớp đã được tạo trong mục 5.9.
1.4 Thực hiện phép biến đổi XSL
V
V
Bạn cần biến đổi một tàiliệuXML thành một tàiliệu khác bằng XSLT
stylesheet.
#
#
Sử dụng lớp System.Xml.Xsl.XslTransform. Nạp XSLT stylesheet bằng phương
thức XslTransform.Load, và tạo tàiliệu kết xuất bằng phương thức Transform
(cần cung cấp tàiliệu nguồn).
XSLT (hay XSL Transforms) là một ngôn ngữ dựa-trên-XML, được thiết kế để biến đổi
một tàiliệuXML thành một tàiliệu khác. XSLT có thể được sử dụng để tạo một tàiliệu
XML mới với cùng dữ
liệu nhưng được sắp xếp theo một cấu trúc khác hoặc để chọn một
tập con dữ liệu trong một tài liệu. Nó cũng có thể được sử dụng để tạo một kiểu tàiliệu
có cấu trúc khác. XSLT thường được sử dụng theo cách này để định dạng một tàiliệu
XML thành một trang HTML.
XSLT là một ngôn ngữ đa năng, và việc tạo XSL Transforms vượt quá ph
ạm vi quyển
sách này. Tuy nhiên, bạn có thể học cách tạo các tàiliệu XSLT đơn giản bằng cách xem
một ví dụ cơ bản. Mục này sẽ biến đổi tàiliệu orders.xml (đã được trình bày trong mục
5.6) thành một tàiliệu HTML và rồi hiển thị kết quả. Để thực hiện phép biến đổi này, bạn
sẽ cần XSLT stylesheet như sau:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >
<xsl:template match="Order">
<html><body><p>
Order <b><xsl:value-of select="Client/@id"/></b>
for <xsl:value-of select="Client/Name"/></p>
<table border="1">
<td>ID</td><td>Name</td><td>Price</td>
<xsl:apply-templates select="Items/Item"/>
</table></body></html>
</xsl:template>
<xsl:template match="Items/Item">
<tr>
<td><xsl:value-of select="@id"/></td>
<td><xsl:value-of select="Name"/></td>
<td><xsl:value-of select="Price"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Về cơ bản, mọi XSL stylesheet gồm một tập các template. Mỗi template so trùng với các
phần tử trong tàiliệu nguồn và rồi mô tả các phần tử được so trùng để tạo nên tàiliệu kết
quả. Để so trùng template, tàiliệu XSLT sử dụng biểu thức XPath, như được mô tả trong
mục 5.6.
Stylesheet vừa trình bày ở trên (orders.xslt) gồm hai template (là các con của phần tử
stylesheet gốc). Template đầu tiên trùng khớ
p với phần tử Order gốc. Khi bộ xử lý XSLT
tìm thấy một phần tử Order, nó sẽ ghi ra các thẻ cần thiết để bắt đầu một bảng HTML với
các tiêu đề cột thích hợp và chèn dữ liệu về khách hàng bằng lệnh value-of (ghi ra kết
quả dạng text của một biểu thức XPath). Trong trường hợp này, các biểu thức XPath
(Client/@id và Client/Name) trùng với đặc tính id và phần tử Name.
K
ế tiếp, lệnh apply-templates được sử dụng để phân nhánh và xử lý các phần tử Item
nằm trong. Điều này là cần thiết vì có thể có nhiều phần tử Item. Mỗi phần tử Item được
so trùng bằng biểu thức Items/Item (nút gốc Order không được chỉ định vì Order chính là
nút hiện tại). Cuối cùng, các thẻ cần thiết sẽ được ghi ra để kết thúc tàiliệu HTML.
Nếu thực thi phép biến đổi này trên file orders.xml (đ
ã trình bày trong mục 5.6), bạn sẽ
nhận được kết quả (tài liệu HTML) như sau:
<html>
<body>
<p>
Order <b>ROS-930252034</b>
for Remarkable Office Supplies</p>
<table border="1">
<td>ID</td>
<td>Name</td>
<td>Price</td>
<tr>
<td>1001</td>
<td>Electronic Protractor</td>
<td>42.99</td>
</tr>
<tr>
<td>1002</td>
<td>Invisible Ink</td>
<td>200.25</td>
</tr>
</table>
</body>
</html>
Để áp dụng một XSLT stylesheet trong .NET, bạn cần sử dụng lớp XslTransform. Ứng
dụng dưới đây áp dụng phép biến đổi và rồi hiển thị file đã được biến đổi trong cửa sổ
trình duyệt web. Trong ví dụ này, mã lệnh đã sử dụng phiên bản nạp chồng của phương
thức Transform để lưu trực tiếp tàiliệu kết quả ra đĩa, mặc dù bạn có thể thu l
ấy và xử lý
nó như một stream bên trong ứng dụng của bạn.
using System;
using System.Windows.Forms;
using System.Xml.Xsl;
public class TransformXml : System.Windows.Forms.Form {
private AxSHDocVw.AxWebBrowser webBrowser;
// (Bỏ qua phần mã designer.)
private void TransformXml_Load(object sender, System.EventArgs e) {
XslTransform transform = new XslTransform();
// Nạp XSL stylesheet.
transform.Load("orders.xslt");
// Biến đổi orders.xml thành orders.html.
transform.Transform("orders.xml", "orders.html", null);
object var = null;
webBrowser.Navigate(
"file:///" + Application.StartupPath + @"\orders.html",
ref var, ref var, ref var, ref var);
}
}
[...]...The image part with relationship ID rId7 was not found in the file Hình 5.5 Kết xuất stylesheet cho orders .xml NET Framework không có điều kiểm nào dùng để thể hiện nội dung HTML Tuy nhiên, chức năng này có thể có được thông qua khả năng liên tác COM nếu bạn sử dụng điều kiểm ActiveX Web Browser (đi cùng Microsoft . thiết kế để biến đổi
một tài liệu XML thành một tài liệu khác. XSLT có thể được sử dụng để tạo một tài liệu
XML mới với cùng dữ
liệu nhưng được sắp xếp. tượng thành tài liệu XML, giải tuần tự hóa tài li
ệu
thành đối tượng, và rồi hiển thị tài liệu này:
using System;
using System .Xml;
using System .Xml. Serialization;