XmlDocument
doc = new XmlDocument();
doc.Load("books.xml");
XmlNodeList
nodeLst = doc.GetElementsByTagName("title");
foreach
(XmlNode node in nodeLst)
listBox1.Items.Add(node.InnerText); // InnerXml / OuterXml
如何插入节点
XmlDocument
doc = new XmlDocument();
doc.Load("books.xml");
XmlElement
newBook = doc.CreateElement("book");
newBook.SetAttribute("genre", "Mystery");
newBook.SetAttribute("publicationdate", "2001");
newBook.SetAttribute("ISBN", "123456789");
XmlElement
newTitle = doc.CreateElement("title");
newTitle.InnerText = "Case of the Missing Cookie";
newBook.AppendChild(newTitle);
XmlElement
newAuthor = doc.CreateElement("author");
newBook.AppendChild(newAuthor);
XmlElement
newName = doc.CreateElement("name");
newName.InnerText = "Cookie Monster";
newAuthor
.AppendChild(newName);
XmlElement
newPrice = doc.CreateElement("price");
newPrice.InnerText = "9.95";
newBook.AppendChild(newPrice);
doc.DocumentElement.AppendChild(newBook);
XmlTextWriter
tr = new XmlTextWriter("booksEdit.xml", null);
tr.Formatting = Formatting.Indented;
//
保存当前节点和子节点
doc.WriteContentTo(tr);
//
只保存当前节点
//_doc.WriteTo(tr);
//_doc.Save(tr);
tr.Close();
XmlNodeList
nodeLst = doc.GetElementsByTagName("title");
foreach
(XmlNode node in nodeLst)
listBox1.Items.Add(node.InnerText);
SelectSingleNode()
和
SelectNodes()
都是在
XmlNode
中定义的
,
而
XmlDocument
是基于
XmlNode
的
.
SelectSingleNode()
返回一个
XmlNode
; SelectNodes()
返回一个
XmlNodeList
;
XmlNode
node = doc.SelectSingleNode("bookstore/book[title='VC
深入浅出
']"
);
XmlNodeList
nodeLst = doc.SelectNodes("/bookstore/book/title");
如果
要写入
XML
流的数据已经准备好
,
最好
选择
XmlTextWriter;
如果
只是建立
XML
文档的一
小部分
或是在不同的地方
插入
节点
,
最好
用
XmlDocument.
希望有一个
流类型
的模型时
,
可以
使
用
XmlReader;
基于
XmlDocument
的
XmlNode
也能遍历
XML,
虽然
灵活性高
,
但
要求的内存较
多
;
将
ADO.NET
数据转换成
XML
文档
XmlDocument
doc = new XmlDocument();
MemoryStream memStrm = new MemoryStream();
//
将数据表转换成
XML,
并放入内存流
,
使用流的好处是不需要将数据写入磁盘
,
并还能使用基本
Stream
类的其它对象
.
//WriteXml
重载方法中
,
其中一个方法需要一个
XmlWriteMode
的枚举参数
;
ds.WriteXml(memStrm, XmlWriteMode.IgnoreSchema);
memStrm.Seek(0, SeekOrigin.Begin);
doc.Load(memStrm);
//936 = GB2312
XmlTextWriter wrt = new XmlTextWriter("Product.xml", System.Text.Encoding.GetEncoding(936));
wrt.Formatting = Formatting.Indented;
doc.WriteContentTo(wrt);
XmlWriteMode
枚举
成员名称
|
说明
|
DiffGram
|
作为
DiffGram
写入整个
DataSet
,包括原始值和当前值。若要生成只包含已更改的值的
DiffGram
,请调用
GetChanges
,然后在返回的
DataSet
上作为
DiffGram
调用
WriteXml
。
|
IgnoreSchema
|
以
XML
数据形式写入
DataSet
的当前内容,不带
XSD
架构。如果无数据加载到
DataSet
中,则不写入任何内容。
|
WriteSchema
|
以
XML
数据形式写入
DataSet
的当前内容,以关系结构作为内联
XSD
架构。如果
DataSet
只有架构而无数据,那么只写入内联架构。如果
DataSet
没有当前架构,则不写入任何内容。
|
上例中先将
XML
放入流
,
然后再调用
WriteContentTo()
方法写入磁盘
,
其实你也可以直接调用
WriteXml()
方法
,
直接
将
XML
文件写入磁盘
.
如果
你只需要将
DataSet
中的表
架构
转换成
XML,
那你可以
使用
WriteXmlSchema()
方法
.
ds.WriteXml("sample.xml", XmlWriteMode.WriteSchema);
上例中
,
使用了
XmlDocument
的对象
doc,
不过将被转换后的
XML
读入
doc
的过程过于复杂
,
先要创建一个流
,
然后再调用
WriteXml()
方法写入流
,
最后再调用
Load()
方法
.
其实
.NET
已经提供了
XmlDataDocument
专门为
XML
和
ADO.NET
服务
.
XmlDocument
的参数是一个
DataSet
的对象
,
实际上
,
如果没有
参数
,
它还是会
创建一个
名为
NewDataSet
的
DataSet,
其中
Tables
中
没有
任何
表
,
并且
你还可以在创建后设置
DataSet
属性
.
XmlDocument
doc = new XmlDocument();
doc = new XmlDataDocument(ds);
如果
DataSet
中有多个表
,
并且表之间存在着
Relations,
怎么办
?
其实
,
工作方式仍旧是酱紫
.
ds.Relations.Add(ds.Tables["Client"].Columns["
客户
ID"
],
ds.Tables["Order"].Columns["
客户
ID"
]);
//
注意
,
此处生成的
Product.xml
是带有架构的
ds.WriteXml("Product.xml", XmlWriteMode.WriteSchema);
将
XML
文档转换成
ADO.NET
数据
ds.ReadXml("Product.xml");
ReadXml()
重载方法中
,
其中有方法需要用到
XmlReadMode
枚举
(
查问
MSDN);
如果你只需要读取架构
,
那可以直接调用
ReadXmlSchema()
方法
.
XPathNavigator
用于从
XML
文档中选择、迭代、编辑数据
.
使用
XPathDocument
创建
XPathNavigator
对象
,
该对象为
只读
,
使用
XmlDocument
创建
XPathNavigator
对象
,
该对象为可
编辑
.
XPathNavigator
对象的只读或可编辑状态是使用
XPathNavigator
类的
CanEdit
属性决定的。
//
使用
XPathDocument
创建的对象只能处于只读状态
XPathDocument
doc = new XPathDocument("books.xml");
// XPathNavigator
包含了移动和选择所需元素的所有方法
XPathNavigator
nav = ((IXPathNavigable)doc).CreateNavigator();
// XPathNodeIterator
迭代器
,
由
Select()
方法返回
,
可以看作
XPath
中的
NodeList
或
NodeSet
XPathNodeIterator
iter = nav.Select("/bookstore/book[@genre='novel']");
//MoveNext():
移动到匹配
XPath
表达式的下一个节点上
.
但是
,
最初
调用
MoveNext()
之后
,
定位在
第一个
节点上
.
while
(iter.MoveNext())
{
//SelectDescendants :
选择当前节点的子代节点中与选择条件匹配的所有子代节点。
XPathNodeIterator
newIter = iter.Current.SelectDescendants(XPathNodeType.Element, false);
// MoveNext() :
移动到匹配
XPath
表达式的
下一个
节点上
,
创建
XPathNodeIterator
while (newIter.MoveNext())
listView1.Items.Add(newIter.Current.Name + ": " + newIter.Current.Value);
}
如何像聚合函数一样
,
将所有书的价格相加
?
listView1.Items.Add("Total Cost = " + nav.Evaluate("sum(/bookstore/book/price)"));
如何插入节点
?
XmlDocument doc = new XmlDocument();
doc.Load("books.xml");
//XPathNavigator
对象由
XmlDocument
对象创建
,
故处于可编辑状态
XPathNavigator nav = doc.CreateNavigator();
if
(nav.CanEdit)
{
XPathNodeIterator
iter = nav.Select("/bookstore/book/price");
//MoveNext():
移动到匹配
XPath
表达式的下一个节点上
.
但是
,
最初
调用
MoveNext()
之后
,
定位在
第一个
节点上
.
while (iter.MoveNext())
{
//
在每一个
<price> </price>
后面插入
iter.Current.InsertAfter("<disc>5</disc>");
}
}
doc.Save("newbooks.xml");
System.Xml.Serialization
命名空间中最重要的类是
XmlSerializer
.
串行化一个对象
,
首先需要实例化一个
XmlSerializer
对象
,
并指定串行化的对象类型
,
然后实例化一个流
/
写入器对象
,
把文件写入流
/
文档
,
最后调用
Serializer()
方法
.
Product
pd = new Product();
pd.ProductID = 200;
pd.CategoryID = 100;
pd.Discontinued = false;
pd.ProductName = "Serialize Objects";
……
XmlSerializer
sr = new XmlSerializer(typeof(Product));
TextWriter
tr = new StreamWriter("Product.xml");
//Serialize()
方法有
9
个重载
,
但每一个方法都需要一个写入数据的流
,
可以是
Stream,TextWriter
或
XmlWriter
sr.Serialize(tr, pd);
//
XmlRootAttribute
、
XmlElementAttribute
和
XmlAttributeAttribute
是
C#
的属性
,
仅是一些声明信息
,
在运行
//
期间由
CLR
获取
.
//
XmlRootAttribute
把这个类
,
在串行化生成的
XML
文档中
,
标识为根元素
[System.Xml.Serialization.XmlRootAttribute()]
public
class Product
{
private int prodId;
private string prodName;
private int suppId;
……
//
这里是
XmlAttributeAttribute
[XmlAttributeAttribute(AttributeName = "Discount")]
public int Discount
{
get { return disc; }
set { disc = value; }
}
// XmlElementAttribute
把下面的成员看做一个
XML
元素
[XmlElementAttribute()]
public int ProductID
{
get { return prodId; }
set { prodId = value; }
}
[XmlElementAttribute()]
public string ProductName
{
get { return prodName; }
set { prodName = value; }
}
[XmlElementAttribute()]
public int SupplierID
{
get { return suppId; }
set { suppId = value; }
}
}
Product.xml
<?
xml
version
=
"1.0"encoding="utf-8"?>
<
Product
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"Discount="0">
<
ProductID
>
200</ProductID>
<
ProductName
>
Serialize Objects</ProductName>
<
SupplierID
>
1</SupplierID>
<
CategoryID
>
100</CategoryID>
<
QuantityPerUnit
>
6</QuantityPerUnit>
<
UnitPrice
>
1000</UnitPrice>
<
UnitsInStock
>
10</UnitsInStock>
<
UnitsOnOrder
>
0</UnitsOnOrder>
<
ReorderLevel
>
1</ReorderLevel>
<
Discontinued
>
false</Discontinued>
</
Product
>
反串行化操作
Product
newPd;
FileStream
f = new FileStream("Product.xml", FileMode.Open);
XmlSerializer
newSr = new XmlSerializer(typeof(Product));
//Deserialize()
方法必须有一个流
/
读取器参数
newPd = (Product)newSr.Deserialize(f);
f.Close();
更为复杂的操作
派生的类
+
返回一个数据的属性
可以看出
,
最后只需要串行化
Inventory
这个类
,
串行化它
,
就需要插入一个属性
,
该属性为每个要添加到数据中的类型包含一个
XmlArrayItem
构造函数
(XmlArrayItem
是由
XmlArrayItemAttribute
类表示的
.NET
属性名
)
XmlArrayItem
构造函数的第一个参数是串行化过程中
,XML
中的元素名
,
如果不写
,
默认会与对象类型名相同
;
第二个
参数是对象的类型
;
public
class Inventory
{
private Product[] stuff;
public Inventory() { }
[XmlArrayItem("Prod", typeof(Product)),XmlArrayItem("Book", typeof(BookProduct))]
public Product[] InventoryItems
{
get { return stuff; }
set { stuff = value; }
}
}
public
class BookProduct : Product
{
private string isbnNum;
public BookProduct() { }
public string ISBN
{
get { return isbnNum; }
set { isbnNum = value; }
}
}
private
void button4_Click(object sender, EventArgs e)
{
//
XmlAttributes
:
表示一个属性对象的集合
//
第一步
:
创建一个
XmlAttributes
对象
,
为每个要重写的数据类型创建一个
XmlElementAttribute
对象
XmlAttributes attrs = new XmlAttributes();
attrs.XmlElements.Add(new XmlElementAttribute("Book", typeof(BookProduct)));
attrs.XmlElements.Add(new XmlElementAttribute("Prod", typeof(Product)));
//
第二步
:
创建
XmlAttributeOverrides
对象
XmlAttributeOverrides
attrOver = new XmlAttributeOverrides();
//
本例中是要重写
Inventory
类中的
InventoryItems
成员
attrOver.Add(typeof(Inventory), "InventoryItems", attrs);
Product newProd = new Product();
BookProduct newBook = new BookProduct();
newProd.ProductID = 100;
newProd.ProductName = "Product Thing";
newProd.SupplierID = 10;
newBook.ProductID = 101;
newBook.ProductName = "How to Use Your New Product Thing";
newBook.SupplierID = 10;
newBook.ISBN = "123456789";
Product[] addProd ={ newProd, newBook };
Inventory inv = new Inventory();
inv.InventoryItems = addProd;
TextWriter tr = new StreamWriter("Product.xml");
XmlSerializer sr = new XmlSerializer(typeof(Inventory), attrOver);
sr.Serialize(tr, inv);
tr.Close();
webBrowser1.Navigate(AppDomain.CurrentDomain.BaseDirectory + "//inventory.xml");
}
Product.xml
<?
xml
version
=
"1.0"encoding="utf-8"?>
<
Inventory
xmlns:xsi
=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd
=
"http://www.w3.org/2001/XMLSchema">
<
Prod
Discount
=
"0">
<
ProductID
>
100</ProductID>
<
ProductName
>
Product Thing</ProductName>
<
SupplierID
>
10</SupplierID>
<
CategoryID
>
0</CategoryID>
<
UnitPrice
>
0</UnitPrice>
<
UnitsInStock
>
0</UnitsInStock>
<
UnitsOnOrder
>
0</UnitsOnOrder>
<
ReorderLevel
>
0</ReorderLevel>
<
Discontinued
>
false</Discontinued>
</
Prod
>
<
Book
Discount
=
"0">
<
ProductID
>
101</ProductID>
<
ProductName
>
How to Use Your New Product Thing</ProductName>
<
SupplierID
>
10</SupplierID>
<
CategoryID
>
0</CategoryID>
<
UnitPrice
>
0</UnitPrice>
<
UnitsInStock
>
0</UnitsInStock>
<
UnitsOnOrder
>
0</UnitsOnOrder>
<
ReorderLevel
>
0</ReorderLevel>
<
Discontinued
>
false</Discontinued>
<
ISBN
>
123456789</ISBN>
</
Book
>
</
Inventory
>
读写
DiffGram
DiffGram
是包含数据在编辑对话前后的
XML
文档
.
大部分的
DBMS
都提供了跟踪或用于提交
/
回滚过程的功能
,
但如果你使用的
DBMS
没有提供这些功能
,
就可以使用
DiffGram.
保存带有
DiffGram
模式的
XML
文档
ds.Tables[0].Rows[0]["
产品名称
"
] = "
新改的
"
;
DataRow
dr = ds.Tables[0].NewRow();
dr["
产品
ID"
] = "1231234";
dr["
产品名称
"
] = "
新加的
"
;
ds.Tables[0].Rows.Add(dr);
//
首先需要保存为一个模式
(
架构
)
文件
,
是为读取
DiffGram
做准备
ds.WriteXmlSchema("author.xdr");
ds.WriteXml("authdiff.xml", XmlWriteMode.DiffGram);
使用
DiffGram
模式读取
XML
文档
DataSet
ds = new DataSet();
//
读取
DiffGram
的模式
(
架构
)
文件
ds.ReadXmlSchema("author.xdr");
ds.ReadXml("authdiff.xml", XmlReadMode.DiffGram);
author.xdr
<?
xml
version
=
"1.0"standalone="yes"?>
<
xs:schema
id
=
"XMLAuthors"xmlns=""xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<
xs:element
name
=
"XMLAuthors"msdata:IsDataSet="true"msdata:UseCurrentLocale="true">
<
xs:complexType
>
<
xs:choice
minOccurs
=
"0"maxOccurs="unbounded">
<
xs:element
name
=
"Authors">
<
xs:complexType
>
<
xs:sequence
>
<
xs:element
name
=
"
产品
ID
"type="xs:int"minOccurs="0" />
<
xs:element
name
=
"
产品名称
"type="xs:string"minOccurs="0" />
<
xs:element
name
=
"
单位数量
"type="xs:string"minOccurs="0" />
<
xs:element
name
=
"
单价
"type="xs:decimal"minOccurs="0" />
<
xs:element
name
=
"
库存量
"type="xs:short"minOccurs="0" />
<
xs:element
name
=
"
订购量
"type="xs:short"minOccurs="0" />
<
xs:element
name
=
"
再订购量
"type="xs:short"minOccurs="0" />
<
xs:element
name
=
"
中止
"type="xs:boolean"minOccurs="0" />
</
xs:sequence
>
</
xs:complexType
>
</
xs:element
>
</
xs:choice
>
</
xs:complexType
>
</
xs:element
>
</
xs:schema
>
authdiff.xml
<?
xml
version
=
"1.0"standalone="yes"?>
<
diffgr:diffgram
xmlns:msdata
=
"urn:schemas-microsoft-com:xml-msdata"xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<
XMLAuthors
>
<
Authors
diffgr:id
=
"Authors1"msdata:rowOrder="0"diffgr:hasChanges="modified">
<
产品
ID
>
1</
产品
ID
>
<
产品名称
>
新改的
</
产品名称
>
<
单位数量
>
每箱
24
瓶
</
单位数量
>
<
单价
>
18.0000</
单价
>
<
库存量
>
39</
库存量
>
<
订购量
>
0</
订购量
>
<
再订购量
>
10</
再订购量
>
<
中止
>
true</
中止
>
</
Authors
>
<
Authors
diffgr:id
=
"Authors2"msdata:rowOrder="1">
<
产品
ID
>
2</
产品
ID
>
<
产品名称
>
WaterBox</
产品名称
>
<
单位数量
>
每箱
24
瓶
</
单位数量
>
<
单价
>
19.0000</
单价
>
<
库存量
>
17</
库存量
>
<
订购量
>
40</
订购量
>
<
再订购量
>
25</
再订购量
>
<
中止
>
false</
中止
>
</
Authors
>
......
<
Authors
diffgr:id
=
"Authors70"msdata:rowOrder="69"diffgr:hasChanges="inserted">
<
产品
ID
>
1231234</
产品
ID
>
<
产品名称
>
新加的
</
产品名称
>
</
Authors
>
</
XMLAuthors
>
<
diffgr:before
>
<
Authors
diffgr:id
=
"Authors1"msdata:rowOrder="0">
<
产品
ID
>
1</
产品
ID
>
<
产品名称
>
苹果汁
</
产品名称
>
<
单位数量
>
每箱
24
瓶
</
单位数量
>
<
单价
>
18.0000</
单价
>
<
库存量
>
39</
库存量
>
<
订购量
>
0</
订购量
>
<
再订购量
>
10</
再订购量
>
<
中止
>
true</
中止
>
</
Authors
>
</
diffgr:before
>
</
diffgr:diffgram
>