14.2 读写XML

  XML和HTML都是基于SGML(Standard Generalized Markup Language,标准通用标记语言)的,但是XML和HTML却有着很大的区别,这些区别不仅仅在于格式上的区别,还在于使用性、可扩展性等等。

14.2.1 XML与HTML
  XML标记语言和HTML标记语言有着极大的不同,在应用程序开发中,XML标记语言能够适应于大部分的应用程序环境和开发需求。这些需求是HTML标记语言无法做到的,XML标记语言和HTML标记语言的具体区别如下所示。
1)HTML标记是固定的,并且是没有层次的,在HTML文档中,用户无法自行创建标签,例如<book>这样的标签浏览器很可能解析不了,HTML中标记的作用是描述数据的显示方式,这种方式只能交付给浏览器进行处理,而HTML文档中的标记都是独立存在的,没有层次。
2)XML的标记不是固定的且是有层次的,在XML文档中,用户可以自行创建标签,例如<day>这样的标签,XML标记不能够描述网页的外观和内容,XML只能够描述内容的数据结构和层次,在浏览器中浏览XML文档,也可以发现XML标记是有层次的。
  在Visual Studio 2008中,.NET Framework提供了System.XML命名空间,该命名空间提供了一组可扩展类使得开发人员能够轻松的读、写、以及编辑XML文本。

14.2.2 创建XML文档
  使用Visual Studio 2008能够创建XML文档,创建和使用XML文档无需XML语法分析器来专门负责分析语法,在.NET Framework中已经集成了可扩展类。右击现有项,单击【添加新项】选项,选择XML文件,
  创建完成后,就需要向XML文档中编写XML标记,以下是一个完整的XML文档示例。
+展开
-XML
<?xml version="1.0" encoding="utf-8" ?>
<Root>
    <ShopInformation area="Asia">
        <Shop place="Wuhan">
            <Name>武汉电脑城</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="ShangHai">
            <Name>武汉电脑城</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>
    <ShopInformation area="USA">
        <Shop place="S">
            <Name>PC STORE</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="S.K">
            <Name>Windows Mobile Store</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>
</Root>

  上述XML文档使用了自定义标记对商城进行了描述,包括商城所在地、商城名称、电话号码以及负责人等。编写XML文档时,开发人员能够自定义标签进行文档描述,但是在XML文档的头部必须进行XML文档声明,示例代码如下所示。
+展开
-XML
<?xml version="1.0" encoding="utf-8" ?>

  上述代码在XML文档头部进行了声明,表示该文档是一个XML文档,并且说明该文档的版本为1.0的XML文档,该文档还可以包含一个encoding属性,指明文档中的编码类型。声明该文档是一个XML文档后,则需要在XML文档中编写根标记,这个标记可以是开发人员自定义标记名称,在这里被命名为Root,示例代码如下。
+展开
-XML
<Root>
<!-- 根标记内的所有内容 -->
</Root>

  上述代码创建了一个根标记,在这里命名为Root。在XML文档中,所有的标记都应该被包含在一个根标记中,这样不仅方便描述也方便查阅。XML文档中的根标记不能够重复使用,如果重复使用则会提示异常。
  在根标记内,应该编写需要描述的信息的标记。在这里,描述一个商城需要的一些属性,包括商城所在的州、所在地以及商城的主营类型等,通过XML标记语言可以自行创建标记来描述,示例代码如下所示。
+展开
-XML
    <ShopInformation area="USA"> <!--地区描述-->
        <Shop place="S"> //位置描述
            <Name>PC STORE</Name><!--商城名称-->
            <Phone>123456789</Phone><!--商城电话-->
            <Seller>J.Dan</Seller><!--商城销售人员-->
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="S.K">
            <Name>Windows Mobile Store</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>

  上述代码对商城的信息进行了描述,这些标签的意义如下所示:
1)ShopInformation:商城信息,包括area属性来描述所在州或板块,这里说明了是在USA地区。
2)Shop:商城在该板块的所在州、省市等信息。
3)Name:商城的名称。
4)Phone:商城的联系电话。
5)Seller:商城的销售人员。
  这些标签都是用户自定义的,XML文档允许开发人员自定义标签并,另外,XML文档也不局限所要描述的对象格式。例如当上述代码也可以编写另外一种样式时,同样能够被XML所识别,示例代码如下所示。
+展开
-XML
    <ShopInformation>
        <Area name="Usa"><!--另一种地区表示方式-->
            <Shop>
                <Name>PC STORE</Name>
                <Phone>123456789</Phone>
                <Seller>J.Dan</Seller>
                <Seller>Bill Gates</Seller>
                <Place>S.K</Place><!--地区直接放在描述中-->
            </Shop>
            <Shop>
                <Name>Windows Mobile Store</Name>
                <Phone>123456789</Phone>
                <Seller>Bill Gates</Seller>
                <Place>S</Place>
            </Shop>
        </Area>
    </ShopInformation>

  技巧:良好的缩进能够让XML文档更加方便阅读,同时XML文档是大小写敏感的,对于XML标记,标记头和标记尾的大小写规则必须匹配。

14.2.3 XML控件
  在ASP.NET中提供了针对XML读写的控件XML控件,XML控件可以很好的解决XML文档的显示问题,如果需要浏览XML文档的数据,则只需要编写XML控件中的DocumentSource属性即可,示例代码如下所示。
+展开
-HTML
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Xml ID="xml1" runat="server" DocumentSource="~/XMLFile1.xml"></asp:Xml><!--使用XML控件-->
    </div>
    </form>
</body>

运行后如图14-3所示。
XML控件
图14-3 XML控件
  运行后会发现XML文档的内容都显示出来了,但是却没有层次感,因为XML控件并没有把记录分开,而是连续的呈现XML文档的内容。如果需要按照规范或开发人员的意愿呈现给浏览器,则必须使用XSL样式表。

14.2.4 XML文件读取类(XmlTextReader)
  XmlTextReader类属于System.Xml命名空间,XmlTextReader类提供对XML数据的快速、单项、无缓冲的数据读取功能,因为XmlTextReader类是基于流的,所以使用XmlTextReader类读取XML内容只能够从前向后读取,而不能逆向读取。
  因为XmlTextReader类的流形式,节约了读取XML文档的时间,也大量的节约了读取XML所需花费的内存空间,当需要读取XML节点时,只需要使用XmlTextReader类的Read()方法即可,示例代码如下所示。
+展开
-C#
            XmlTextReader rd = new XmlTextReader(Server.MapPath("XMLFile1.xml")); //构造函数
            while (rd.Read())//遍历节点
            {
                Response.Write("Node Type is : " + rd.NodeType +" <br/>");//输出Node
                Response.Write("Name is : " + rd.Name + " <br/>");//输出Name
                Response.Write("Value is :" + rd.Value + " <br/>"); //输出Value
                Response.Write("<hr/>");
            }

  上述代码使用XmlTextReader类的构造函数创建了XmlTextReader对象,并通过使用XmlTextReader类的Read()方法进行XmlTextReader对象的遍历。遍历XML文档后,需要使用Close方法进行XmlTextReader对象的关闭操作,这一点是非常重要的,如果不使用XmlTextReader类的Close方法,则相应的XML文件正在被进程使用,只有使用了Close方法才能将相应的文件关闭掉。示例代码如下所示。
+展开
-C#
rd.Close();//关闭Reader


  在使用XmlTextReader类读取XML文件中相应的节点时,XmlTextReader类的NodeType会检查节点的类型,而XmlTextReader类的Name和Value会分别检查节点的名称和值,相应的XML代码如下所示。
+展开
-XML
        <Shop place="Wuhan">
            <Name>武汉电脑城</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>

  上述代码中,使用XmlTextReader类进行读取,则Shop节点的NodeType为Element,Name的值为Shop,Value的值为空。XML文档中不止以上几种节点类型,XmlNodeType也包括其他节点类型,这些类型如下所示。
1)Attribut:XML元素的属性。
2)CDATA:用于转义文本块,避免将文本块识别为标记。
3)Comment:XML文档的注释。
4)Document:作为文档树的根的文档对象,可供每个XML文档进行访问。
5)DocumentType:XML文档类型的声明。
6)Element:XML元素。
7)EndElement:当XmlTextReader达到元素末尾时返回。
8)Entity:实体声明。
9)Text:元素的文本内容。
10)WhiteSpace:标记间的空白。
11)XmlDeclaration:XML节点声明,它是文档中的第一个节点。
  在XML文档中,空白标记和根节点的节点类型是不相同的,XmlTextReader类读取XML文件并遍历节点类型,根节点和空白节点遍历后结果如下所示。
Node Type is:XmlDeclaration
Nameis:xml
Value is:version="1.0" encoding="utf-8"
Node Type is:Whitespace
Nameis:
Value is:

  其中根节点的节点类型为XmlDeclaration,Value值为version="1.0" encoding="utf-8"。

14.2.5 XML文件编写类(XmlTextWriter)
  XmlTextWriter类属于System.Xml命名空间,同XmlTextReader类相同的是,XmlTextWriter类同样提供没有缓存,直向前的方式进行XML文件操作,但是与XmlTextReader类操作相反,XmlTextWriter类执行的是写操作。XmlTextWriter类的构造函数包括三种重载形式,分别为一个字符串、一个流对象和一个TextWriter对象。通过使用XmlTextWriter类可以动态的创建XML文档,示例代码如下所示。
+展开
-C#
            XmlTextWriter wr = new XmlTextWriter("newXml.xml"null);//读取XML
            try
            {
                wr.Formatting = Formatting.Indented;//格式化输出
                wr.WriteStartDocument();//开始编写文档
                wr.WriteStartElement("ShopInformation");//编写节点
                wr.WriteStartElement("Shop");//编写节点
                wr.WriteAttributeString("place""北京");//编写节点
                wr.WriteElementString("Name""中关村");//编写节点
                wr.WriteElementString("Phone""123456"); //编写节点
                wr.WriteElementString("Seller""Guojing");//编写节点
                wr.WriteEndElement();//结束节点编写
                wr.WriteEndElement();//结束节点编写
                Response.Write("操作成功");
            }
            catch
            {
                Response.Write("操作失败");
            }

  上述代码创建了一个XmlTextWriter对象并通过XmlTextWriter对象编写XML文档,在使用XmlTextWriter类构造函数时,可以指定编码类型,或使用默认的编码类型,若使用默认的编码类型,参数传递null即可,默认编码类型将为UTF-8,示例代码如下所示。
+展开
-C#
XmlTextWriter wr = new XmlTextWriter("newXml.xml"null);//创建写对象

  使用了XmlTextWriter类创建对象后,则需要使用XmlTextWriter对象的Formatting方法指定输出的格式,示例代码如下所示。
+展开
-C#
wr.Formatting = Formatting.Indented;//格式化输出

  指定了输出格式之后,则需要开始为XML文档创建节点,在创建节点前,首先需要声明XML文档,则必须输出<?xml version="1.0" encoding="utf-8" ?>声明,声明1.0版本的xml文档代码如下所示。
+展开
-C#
wr.WriteStartDocument();//开始编写节点

声明文档后就可以使用WriteStartElement进行节点的创建,创建节点代码如下所示。
+展开
-C#
wr.WriteStartElement("Shop");//开始编写节点

  上述代码创建了Shop节点,如果需要为该节点创建place=“北京”属性则需要使用WriteAttributeString方法进行创建,示例代码如下所示。
+展开
-C#
wr.WriteAttributeString("place""北京");//编写属性

创建了父节点之后,可以通过WriteElementString方法创建子节点,示例代码如下所示。
+展开
-C#
wr.WriteElementString("Name""中关村");//创建子节点

节点全部创建完成后,需要使用WriteEndElement方法进行尾节点的编写,示例代码如下所示。
+展开
-C#
wr.WriteEndElement();//结束节点编写

一个XML文档就编写完毕了,编写完成并不能自动的更新XML文档,还需要使用Flush方法进行数据更新,更新完毕后还需要关闭XmlTextWriter对象示例代码如下所示。
+展开
-C#
wr.Flush();//更新文件
wr.Close();//结束写对象

使用Flush方法就能够将XML数据保存在文件中,运行后XML文档结构如下所示。
+展开
-XML
<?xml version="1.0" encoding="utf-8" ?>
<ShopInformation>
    <Shop place="北京">
        <Name>中关村</Name>
        <Phone>123456</Phone>
        <Seller>Guojing</Seller>
    </Shop>
</ShopInformation>


14.2.6 XML文本文档类(XmlDocument)
  XML文档在内存中是以DOM为表现形式的,DOM(Document Object Model)是对象化模型,DOM是以树的节点形式来标识XML数据,14.2.2中的XML文档读入DOM结构中,则在内存中的构造图如图14-5所示。
XML文档构造
图14-5 XML文档构造
  XmlDocument类同样也属于命名空间System.Xml,XmlDocument类可以实现第一、第二级的W3C DOM。它使用DOM以一个层次结构树的形式将整个XML数据加载到内存中,从而能够使开发人员能够对内存中的任意节点进行访问、插入、更新和删除。由于XmlDocument类,简化开发人员对XML文档进行访问、插入和删除等操作。
  XmlDocument类继承自System.Xml.XmlNode,该抽象类表示单个节点并具有基本的属性和方法来操作节点。利用XmlDocument对象的DocumentElement属性能够表示单个节点并进行操作。XmlDocument对象的DocumentElement返回一个指向文档元素的索引,可以通过读取给定的节点的HanChildNodes属性判断是否包括子节点。另外,使用XmlDocument对象的HasChildNodes和ChildNodes属性可以读取和遍历XML文件,示例代码如下所示。
+展开
-C#
        protected void Page_Load(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();//创建XmlDocument对象
            doc.Load(Server.MapPath("newXml.xml"));//载入文件
            Response.Write("读取中..<hr/>");
            XmlNode node = doc.DocumentElement; //读取节点
            output(node); //使用输出函数
            Response.Write("读取完毕..<hr/>");//输出HTML字串
        }
        protected void output(XmlNode node)
        {
            if (node != null)//如果节点不等于空
            {
                format(node);//格式化输出
            }
            if (node.HasChildNodes)//判断是否包括子节点
            {
                node = node.FirstChild;//获取子节点
                while (node != null)
                {
                    output(node);//使用递归
                    node = node.NextSibling;//遍历节点值和信息
                }
            }
        }
        protected void format(XmlNode node)
        {
            if (!node.HasChildNodes)//判断是否包括子节点
            {
                Response.Write("node name is" + node.Name);//输出节点
                Response.Write("node value is" + node.Value);//输出节点
                Response.Write("<br/>");
            }
            else
            {
                Response.Write(node.Name);
                if (XmlNodeType.Element == node.NodeType)//遍历节点
                {
                    XmlNamedNodeMap map = node.Attributes;//遍历节点
                    foreach (XmlNode att in map)
                    {
                        Response.Write("attrnode name is" + att.Name);//格式化输出节点
                        Response.Write("attrnode value is" + att.Value);//格式化输出节点
                        Response.Write("<br/>");
                    }
                }
            }
        }

  上述代码通过使用XmlDocument类遍历节点,使用XmlDocument类遍历节点,首先需要创建一个XmlDocument对象,并使用Load方法加载一个XML文档,示例代码如下所示。
+展开
-C#
XmlDocument doc = new XmlDocument();//创建XmlDocument对象
doc.Load(Server.MapPath("newXml.xml"));//载入XML文件

  创建对象之后,则需要使用递归的方法遍历显示每个节点。在遍历节点的过程中,需要对每个节点进行是否有子节点的判断,如果包括子节点,则先输出子节点,如果没有子节点则继续输出根节点。XmlDocument对象也可以向XML文档中添加一个新的元素,示例代码如下所示。
+展开
-C#
            XmlDocument doc = new XmlDocument(); //创建XmlDocument对象
            doc.Load(Server.MapPath("newXml.xml"));//载入XML文件
            XmlNode node = doc.DocumentElement; //创建节点对象
            node.RemoveChild(node.FirstChild);//移除根节点

  上述代码使用了XmlDocument对象的Load方法载入XML文档,当需要插入XML数据时,则先需要移除根节点,移除根节点之后就能够开始添加节点,示例代码如下所示。
+展开
-C#
            XmlNode Shop = doc.CreateElement("Shop");//创建节点Shop
            XmlNode shop1 = doc.CreateElement("Name");//创建节点Name
            XmlNode shop2 = doc.CreateElement("Phone");//创建节点Phone
            XmlNode shop3 = doc.CreateElement("Seller");//创建节点Seller
            XmlNode NameText = doc.CreateTextNode("NameText");//创建节点文本
            XmlNode PhoneText = doc.CreateTextNode("PhoneText"); //创建节点文本
            XmlNode SellerText = doc.CreateTextNode("SellerText");//创建节点文本
            shop1.AppendChild(NameText);//添加文本
            shop2.AppendChild(PhoneText); //添加文本
            shop3.AppendChild(SellerText);//添加文本
            Shop.AppendChild(shop1);//添加Shop子节点
            Shop.AppendChild(shop2); //添加Shop子节点
            Shop.AppendChild(shop3); //添加Shop子节点
            node.AppendChild(Shop); //添加Shop节点

  上述代码分别为节点添加子节点,并为子节点添加文本,添加完成后,需要使用XmlDocument对象的Save方法进行保存,示例代码如下所示。
+展开
-C#
 doc.Save("newXml.xml");

  使用XmlDocument对象的Save方法即可将XML内容保存在XML文档中。使用XmlDocument对象不仅能够读取,新增XML文档,还支持修改、删除等操作,例如使用PrependChild和InsertBefore,InsertAfter等方法进行新增和删除节点和子节点操作。

加支付宝好友偷能量挖...


评论(0)网络
阅读(141)喜欢(0)Asp.Net/C#/WCF