C#-操作XML笔记(补充中...)





.NET中使用DOM 1

XMLADO.NET 3

XPathNavigator 5

XML中串行化 6

读写DiffGram 13

 

.NET中使用DOM

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;基于XmlDocumentXmlNode也能遍历XML,虽然灵活性高,要求的内存较;

 

 

XMLADO.NET

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专门为XMLADO.NET服务. XmlDocument的参数是一个DataSet的对象,实际上,如果没有参数,它还是会创建一个名为NewDataSetDataSet,其中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

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中的NodeListNodeSet

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");

 

 

 

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,TextWriterXmlWriter

sr.Serialize(tr, pd);

// XmlRootAttributeXmlElementAttributeXmlAttributeAttribute 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>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值