文档章节

四、XmlReader与 XMLWriter(抽象类)

o
 osc_pn11u1x9
发布于 2018/08/06 10:09
字数 1348
阅读 10
收藏 0

一、概述

XMLReader为抽象类,其派生类有:XmlDictionaryReader、XmlNodeReader、XmlTextReader(与IO命名空间中的TextReader对象一起使用)、XmlValidatingReader(添加了DTD和模式验证,提供数据的有效性验证)。

    •XmlReader reader =new XmlTextReader(xmlFile);
    •XmlReader reader =new XmlNodeReader(xmNode);

XMLWriter为抽象类,其派生类有XmlTextWriter与XmlQueryWriter类。

二、XMLReader

1、概述

XmlDocument和XElement在读取Xml时要将整个Xml文档放到内存中去操作,这样做操作简单,但是很费内存。而在有些场景下我们必须考虑尽可能节省内存,这时候就该XmlReader和XmlWriter出场了。

XmlReader非常类似于SAX。它们最大的区别是SAX是一种推模型(所有XML数据都必须由应用程序 处理,无论是否需要这些数据),XmlReader是一种拉模型(如果不需要所有的数据,就不需要处理它们)。

XmlReader读取Xml需要通过Read()实例方法,不断读取Xml文档中的声明,节点开始,节点内容,节点结束,以及空白等等,直到文档结束,Read()方法返回false。

2、用法

(1)使用静态方法Create(),返回一个XmlReader对象。

(2)Read()方法可以进入下一个节点。

XmlReader类还可以读取强类型化的数据,它有几个ReadValuesAs方法,如、ReadValueAsDouble、ReadValueAsBoolean等。

3、检索属性数据

AttributeCountry属性确定属性个数。GetAttribute()方法按照名称或索引来获取属性,如果要一次迭代一个属性就可以使用MoveToFirstAttribute()和MoveToNextAttribute()方法。

XmlReader tr = XmlReader.Create("book.xml");
 while (tr.Read()){
 if (tr.NodeType == XmlNodeType.Element){
   for (int i = 0; i < tr.AttributeCount; i++){
     richTextBox1.AppendText(tr.GetAttribute(i)+"\r\n");
     }
   }
}

4、使用XmlReader类进行验证

有时不但要知道文档的格式是规范的,还是确定文档是有效的。

XmlReader可以使用XmlReaderSettings,根据XSD模式验证XML。XSD模式添加到XMLSchemaSet中,通过Schema属性可以访问XMLSchemaSet。XsdValidate属性还必须设置为ture,这个属性默认为flase.

5、举例:

XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
XmlReader reader = XmlReader.Create("Customer2.xml", settings);//settings参数 为可选。
List<CustomerInfo> lists = new List<CustomerInfo>();
CustomerInfo cust = null;

while (reader.Read())//读取下一个节点
{
    if (reader.NodeType == XmlNodeType.Element)
    {
        switch (reader.Name)
        {
            case "row":
                cust = new CustomerInfo();
                if (reader.HasAttributes)//因属性不是文档结构的一部分,要专门检查。属性HasValue是否有值;IsEmptyElement:是否为空元素
                {
                    cust.AppId = reader.GetAttribute("AppID");
                    cust.Version = reader.GetAttribute("Version");
                }
                break;

            case "CustomerID":
                cust.CustomerID = reader.ReadString();
                break;

            case "CompanyName":
                cust.CompanyName = reader.ReadString();
                break;
            default:
                break;

        }
    }
}

6、读取字节数据

下面的示例读取一个内联 BinHex 编码图像。 BinHex 数据嵌入到 <image> 元素中。 BinaryWriter 用于创建一个新的二进制数据文件。

public static void BinHexDecodeImageFile() {

  byte[] buffer = new byte[1000];
  int readBytes = 0;

  using (XmlReader reader = XmlReader.Create("output.xml")) {
                       
        FileStream outputFile = new FileStream(@"C:\artFiles\data\newImage.jpg", FileMode.OpenOrCreate, 
                                                                      FileAccess.Write, FileShare.Write);
        // Read to the image element.
        reader.ReadToFollowing("image");
        // Read the BinHex data.
        Console.WriteLine("\r\nReading BinHex...");
        BinaryWriter bw = new BinaryWriter(outputFile);
        while ((readBytes = reader.ReadElementContentAsBinHex(buffer, 0, 50))>0) {
            bw.Write(buffer, 0, readBytes);
        }
        outputFile.Close();
        
  }
}

三 、XMLWriter

与XmlReader一样,XmlWriter类以只向前、未缓存的方式 进行写入。

1.如何使用XmlWriter写Xml文档声明

WriteStartDocument方法可以接受一个bool参数(表示standalone,是否为独立文档)或者不指定参数standalone保持默认值

xmlWriter.WriteStartDocument(false|true);

注意在使用WriteStartDocument方法后最好调用xmlWrite.WriteEndDocument()方法来关闭所有可能未关闭标签

2.如何使用XmlWriter写xml节点以及属性

//写节点
xmlWriter.WriteStartElement("cat");

//给节点添加属性
xmlWriter.WriteAttributeString("color", "white");

//给节点内部添加文本
xmlWriter.WriteString("I'm a cat");
xmlWriter.WriteEndElement(); 

或者通过WriteElementString(string,string)方法写xml节点同时写下节点值,如下
xmlWriter.WriteElementString("pig", "pig is great");

3.如何写CData

xmlWriter.WriteCData("<strong>dog is dog</strong>");

4.如何使用XmlWriter添加注释

xmlWriter.WriteComment("*** ");

5.如何设置XmlWriter的输出格式,解决输出UTF-16问题

设置xml输出格式,需要通过XmlWriterSettings类,如下代码

XmlWriterSettings settings = new XmlWriterSettings();

//要求缩进
settings.Indent = true;

//注意如果不设置encoding默认将输出utf-16
 //注意这儿不能直接用Encoding.UTF8如果用Encoding.UTF8将在输出文本的最前面添加4个字节的非xml内容
settings.Encoding = new UTF8Encoding(false);

 //设置换行符
settings.NewLineChars = Environment.NewLine;

6、写入其他对象中

XmlWriter类可以把Xml写入一个流、文件、StringBuilder、TextWriter或另一个XmlWriter对象中。

7、命名空间的支持

XmlTextWriter w = new XmlTextWriter(Console.Out);
w.WriteStartElement("x","root","urn:1");
w.WriteStartElement("y","item","urn:1");
w.WriteAttributeString("abc","urn:1","xyz");
w.WriteEndElement();
w.WriteEndElement();
w.Close();

8、完整的代码示例如下:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\t";
settings.NewLineOnAttributes = false;
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.OmitXmlDeclaration = false;

   //注意如果不设置encoding默认将输出utf-16
   //注意这儿不能直接用Encoding.UTF8如果用Encoding.UTF8将在输出文本的最前面添加4个字节的非xml内容
   settings.Encoding = new UTF8Encoding(false);

   //设置换行符
   settings.NewLineChars = Environment.NewLine;


XmlWriter writer = XmlWriter.Create("CustomerNewElementArribute.xml", settings);//settings参数 为可选。
// 使用xmlwriter写入StringBuiler和Stream:
// StringBuilder builder = new StringBuilder();
// XmlWriter writer = XmlWriter.Create(builder, settings);
//MemoryStream stream = new MemoryStream();
//XmlWriter writer = XmlWriter.Create(stream, settings);
writer.WriteStartDocument();//写Xml声明:可选参数表示standalone,是否为独立文档
writer.WriteComment("XXX"); //写注释<!--和-->
writer.WriteStartElement("Table");//写复杂元素(元素含有子元素)
for (int i = 1; i < 10; i++)
{
    writer.WriteStartElement("row");
    writer.WriteAttributeString("Version", "2.0");
    writer.WriteAttributeString("AppID", "111");
    writer.WriteElementString("CustomerID", "cmz" + i.ToString());//写简单元素
    writer.WriteElementString("CompanyName", "程沐喆" + i.ToString());
    writer.WriteEndElement();
}

writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
writer.Close();

9、用 WriteBinHex 方法编写 BinHex 数据

//用 WriteBinHex 方法编写 BinHex 数据。 BinHex 数据嵌入在 <image> 元素。
int bufferSize = 1000;
byte[] buffer = new byte[bufferSize];
int readBytes = 0;

using (XmlWriter writer = XmlWriter.Create("output.xml"))
{
    FileStream inputFile = new FileStream(@"C:\sunset.jpg", FileMode.OpenOrCreate,
                                                                    FileAccess.Read, FileShare.Read);
    writer.WriteStartDocument();
    writer.WriteStartElement("image");
    BinaryReader br = new BinaryReader(inputFile);
    Console.WriteLine("\r\nWriting BinHex data...");

    do
    {
        readBytes = br.Read(buffer, 0, bufferSize);
        writer.WriteBinHex(buffer, 0, readBytes);
    } while (bufferSize <= readBytes);
    br.Close();

    writer.WriteEndElement();// </image>
    writer.WriteEndDocument();
}
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

pycurl libcurl link-time ssl backend (nss)

pip uninstall pycurlecho 'pycurl==7.19.5.1 --global-option="--with-nss"' > requires.pypip install -r requires.py...

小红手
37分钟前
17
0
计算机网络性能衡量

1、速率 单位时间(s)内传输信息(bit)量 单位:KB/s, MB/s, Gb/s K = 10^3 ,M = 10^6, G=10^9 一般表示的是理想的传输速率 2、带宽 计算机网络中的带宽和通信等领域的带宽概念不一样,计算机网...

osc_np3y0rbq
37分钟前
3
0
互联网掀起农家乐,巨头上演AI掘金战

配图来自Canva **前有网易、阿里AI养猪,后有腾讯AI养鹅,互联网大佬们纷纷玩起了“农家乐”,互联网的生意在尖端技术的引领之下频频跨界,巨头之间的较量也从线上延伸至线下。**自古“民以食...

osc_5cok9i01
39分钟前
9
0
原来!我在4年前就开始体验雾游戏了!

前有云游戏后有雾游戏,游戏的方式看来起来越来越多种多样。那么“震撼业界”的雾游戏到底是什么来头?它依靠什么改变游戏界?它的原理又是什么? 本月月初,著名的日本游戏杂志《Fami通》表...

osc_j34n26zn
40分钟前
11
0
活动预告|田溯宁与你相约GSMA Thrive·万物生晖,分享5G风口下的创新与投资洞察

在万物互联的时代背景下,5G+AI+IoT的技术变革与融合,正在引发一场深刻的全产业创新与变革。5G技术创新、行业应用及投资机遇已成为科技行业所瞩目的焦点。 6月30日,宽带资本董事长田溯宁将...

osc_0qnrwmy3
41分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部