XML对WEB开发的意义

  XML技术对WEB开发具有重大意义。若要开发高水平的WEB系统,应当好好使用XML技术。 XML和HTML

    XML和HTML都源自SGML,具有相同的来源,而且两者都是采用尖括号的标记语言,两者具有很大的相似性。使用XML完全可以模拟出HTML,而且W3C提出了现代WEB站点应当采用的XHTML标准就是XML和HTML的结合。

    在使用ASP.NET开发WEB系统中,除了使用ASP.NET控件展示数据外,还需要由程序拼凑出大量的HTML代码来展现数据。简单的 进行字符串连接操作来生成HTML页面不是一种可持续性的软件开发和维护的过程。程序代码很容易杂乱无章,生成的HTML代码可读性不好。若在生成 HTML代码的过程借鉴XML技术则有助于改善这种问题,从而能更好的控制WEB软件的开发过程,提高软件质量。

XML和WebService

    WebService基础就是XML,WebService的原理是将编程对象序列化成一个XML文档,然后通过HTTP协议传递给客户 端,客户端接受这个XML文档,通过反序列化重现编程对象。因此WebService的基础就是XML序列化技术。在开发和调试稍微复杂的 WebService是需要一定的XML技术基础。

Ajax技术的底层也是使用XML来传递数据的,可以看作一种特殊的WebService。可以这样比喻,WebService是WEB系统的公开方法,而Ajax则是私有方法。

XML/XSLT提供一种全新的开发模式

    XML/XSLT两项技术的配合可以提供一种全新的WEB系统开发模式。在这种模式下,页面将需要显示的纯粹的数据组织生成一个XML文 档,并配上XSL转换信息头,然后发送到客户端,在客户端IE浏览器接受解析XML文档,根据其中的XSL转换头信息再下载XSLT文档,执行XSLT转 换,然后才显示转换的结果。此时WEB页面既能正常的使用指定的格式显示数据,而且本身就是一个可供其它程序调用的WebService。该页面的输出的 源代码就是XML文档,而且只有IE等浏览器类型软件才处理XSLT转换信息头,其他程序是会忽略掉这个信息的。此时页面具有双重功能,便于代码的集成开 发和维护。

关于XSLT下节课程将详细介绍。

使用C#输出XML

    接下来我们将使用C#进行实际的XML开发,由于XML技术对WEB开发特别有用,因此将使用ASP.NET来演示使用C#进行XML开发。此处演示程序已经写好,现在对程序代码进行详细说明。

    本程序是一个ASP.NET程序,大家获得程序代码后要在IIS中设置虚拟目录,由于程序还需要访问程序目录下的一些文件,因此还需要进行一些权限的配置。程序目录下的 demomdb.mdb 是程序使用的数据库文件。

    网站配置完毕后,我们在浏览器中输入网站的地址即可打开它的默认页面。可以看到默认页面上有些程序内容的简单说明。

    首先我们看看 recordxml.aspx 页面,我们看看 recordxml.aspx 的 HTML页面代码,可以看到该页面HTML代码很简单,只有一行。因此该页面的所有内容都是用C#代码生成的。

我们切换到该页面的C#代码,可以看到在 Page_Load 函数里面添加了代码输出页面内容。代码内容为

// 此处使用 XmlTextWriter 来快速输出XML文档内容.不构造XML文档对象结构
this.Response.ContentEncoding = System.Text.Encoding.GetEncoding( 936 );
this.Response.ContentType = "text/xml";
// 连接数据库
using( System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection())
{
    conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
        + this.Server.MapPath("demomdb.mdb");
    conn.Open();
    // 查询数据库
    using( System.Data.OleDb.OleDbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "Select * From Customers";
        System.Data.OleDb.OleDbDataReader reader = cmd.ExecuteReader();
        // 获得所有字段名
        int FieldCount = reader.FieldCount ;
        string[] FieldNames = new string[ FieldCount ] ;
        for( int iCount = 0 ; iCount < FieldCount ; iCount ++ )
        {
            FieldNames[ iCount ] = reader.GetName( iCount );
        }
        // 生成一个XML文档书写器
        System.Xml.XmlTextWriter xmlwriter = new System.Xml.XmlTextWriter( this.Response.Output );
        xmlwriter.Indentation = 3 ;
        xmlwriter.IndentChar = ' ';
        xmlwriter.Formatting = System.Xml.Formatting.Indented ;
        // 开始输出XML文档
        xmlwriter.WriteStartDocument();
        // 输出XSLT样式表信息头
        string strXSLRef = this.Request.QueryString["xsl"] ;
        if( strXSLRef != null && strXSLRef.Length > 0 )
        {
            xmlwriter.WriteProcessingInstruction(
                "xml-stylesheet" ,
                "type='text/xsl' href='" + strXSLRef + "'");
        }
        xmlwriter.WriteStartElement("Table");
        while( reader.Read())
        {
            // 输出一条记录
            xmlwriter.WriteStartElement("Record");
            for( int iCount = 0 ; iCount < FieldCount ; iCount ++ )
            {
                // 输出一个字段值
                xmlwriter.WriteStartElement( FieldNames[ iCount ] );
                object v = reader.GetValue( iCount );
                if( v == null || DBNull.Value.Equals( v ))
                {
                    xmlwriter.WriteAttributeString("Null" , "1");
                }
                else
                {
                    xmlwriter.WriteString( Convert.ToString( v ));
                }
                xmlwriter.WriteEndElement();
            }
            xmlwriter.WriteEndElement();
        }//while( reader.Read())
        reader.Close();
        xmlwriter.WriteEndElement();
        xmlwriter.WriteEndDocument();
        xmlwriter.Close();
    }//using( System.Data.OleDb.OleDbCommand cmd = conn.CreateCommand())
}//using( System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection())

Page_Load 函数的执行流程为

设置HTTP输出类型

    首先设置HTTP的输出类型,我们设置输出的编码格式为 GB2312,此处使用 GetEncoding(936 ) 就是获得GB2312的编码格式。

    我们还设置 ContentType 来设置文档的输出格式。大家若了解一些HTTP传输协议的都知道,ContentType属性描述了文档输出类型,当文档传递到客户端时,客户端浏览器获 得ContentType属性值,查询注册表和Windows中注册的COM信息,获得该属性值确定的文件类型,然后使用相应的模式显示文档。比如若设置 ContentType属性为application/vnd.ms-excel ,则客户端浏览器查询注册表得知对应的文件类型信息在注册项目 HKEY_CLASS_ROOT\.xls下面,本地文件类型为”Excel.Sheet.8”,然后又根据其他信息转而调用EXCEL的COM组件来显示获得的HTTP文档。

    从ContentType属性的说明我们可以了解,很深入的掌握WEB开发,有时候是需要了解一些Windows编程的知识,因为B/S系统的客户端,也就是各种浏览器,特别是IE浏览器就是比较复杂的Windows程序。

查询数据库

    设置了HTTP文档输出模式后,我们开始输出XML文档内容,首先是连接数据库,使用了程序目录下的demomdb.mdb数据库,执行一个SQL查询,获得一个数据读取器reader。

使用XmlTextWriter输出XML文档

    查询得到数据后,我们就可以遍历查询所得的数据库记录,开始输出XML文档,此处我们使用XmlTextWriter输出文档。

    输出XML文档我们有两种方式,一种是使用XmlTextWriter输出,另外一种是从XmlDocument类型开始构造XML文档对象结构,然后使用XmlDocument的Save方法输出XML文档。两种方法有各自特点。

    使用XmlTextWriter是只写的向前的快速输出XML文档,而且输出时不能访问已经输出的XML文档内容,不能修改已经生成的XML文档。这种方法速度快,占用内存少,但不够灵活。

    而使用XmlDocument类型构造XML文档结构后再输出XML文档的方法比较灵活,我们可以随时访问和修改已经输出的Xml文档。这种方法速度慢,占用内存多,但很灵活。

    在这里我们要尝试使用XmlTextWriter来输出XML文档,在另外的一个页码使用XmlDocument输出XML文档。

    我们首先在页面输出流上新建一个XmlTextWriter对象,设置它启动缩进。它的Indentation,IndentChar和 Formating就是控制缩进样式,具体说明可以查看MSDN。XML文档缩进是为了改善XML文档的可读性,有缩进的XML文档便于人们直接阅读和修 改,但对应用程序来说,XML文档是否有缩进是没差别的。

    XmlTextWriter是一个基于其他流的针对输出XML文档的包装,它本身不能打开文件,因此在初始化XmlTextWriter时 必须指明底层的输出对象,输出对象可以为流或者文本书写器。理论上我们可以使用字符串拼凑来生成XML文档,但实际开发中使用字符串拼凑XML文档不是明 智之举,建议使用XmlTextWriter。

    我们在web开发中有时会使用字符串拼凑来生成HTML文档,由于HTML文档没有很严格的语法限制,IE浏览器能解释劣质的HTML代 码,因此有时会有开发者这样字符串拼凑HTML文档,但这会导致代码比较杂乱,可读性不好。而XML文档具有很严格的语法检查,只要一个XML语法错误就 会导致整个XML文档解析错误,因此我们应当使用XmlTextWriter,因此它能帮助我们检查基本的XML语法,确保我们能输出合格的XML文档。

    我们调用WriteStartDocument来开始输出 XML文档,XmlTextWriter提供了很多配对使用的成员,使用一个方法后需要使用另外一个配对的方法。比如 WriteStartDocument和WriteEndDocument配对,WriteStartElement和WriteEndElement配 对,配对的方法必须成对调用。此处我们使用WriteStartDocument开始书写Xml文档,我们就必须使用WriteEndDocument 来完成输出XML文档的。而且在使用XmlTextWriter输出XML文档的时候,WriteStartDocument必须是第一个调用的方法。

    然后我们使用一个名称为xsl的页面参数来输出XML文档的xml-stylesheet信息头,关于XSL下节课将详细介绍,在本节课不管这个参数。

    我们调用WriteStartElement 方法来输出XML文档的根节点,这里参数为字符串 “Table” , 则表示输出的XML文档的根节点名称为Table

    然后我们使用数据库数据读取器的Read函数来遍历所有的 查询的数据,对于每一条记录,使用XML书写器的WriteStartElement方法来输出XML元素,这里参数为字符串”Record”,表示输出 的XML元素名为Record,而且这个节点添加到XML文档的根节点下。

    对于每一条记录我们还遍历其所有的字段值,对每一个字段值使用WriteStartElement新增一个XML元素,元素名称就是各个字段的名称。若字段值是空则使用WriteAttributeString输出名为Null 的XML属性,否则使用WriteString来输出字段值的字符串表达值。

    由于WriteStartElement和 WriteEndElement配对使用,因此每输出完一个XML元素后需要调用WriteEndElement来结束输出XML元素。当所有的内容输出 完毕后我们调用WriteEndDocument来结束输出整个XML文档的。

使用XmlDocument输出XML文档

    页面record.aspx功能和recordxml.aspx类似。但它使用 XmlDocument来构造XML文档对象结构,然后输出XML文档。现对其过程进行说明。

    打开record.aspx的HTML代码,可以看到代码非常简单,只有一行,所有的页面输出都在程序代码中实现。打开它的C#代码,可以看到在Page_Load 方法中添加了代码执行页面输出,其代码为

// 此处代码动态构造 XmlDocument对象 来输出XML文档
System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
XmlDoc.AppendChild( XmlDoc.CreateElement("Table"));
// 连接数据库
using( System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection())
{
    conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
        + this.Server.MapPath("demomdb.mdb");
    conn.Open();
    // 查询数据库
    using( System.Data.OleDb.OleDbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "Select * From Customers";
        System.Data.OleDb.OleDbDataReader reader = cmd.ExecuteReader();
        // 获得所有字段名
        int FieldCount = reader.FieldCount ;
        string[] FieldNames = new string[ FieldCount ] ;
        for( int iCount = 0 ; iCount < FieldCount ; iCount ++ )
        {
            FieldNames[ iCount ] = reader.GetName( iCount );
        }
        while( reader.Read())
        {
            // 输出一条记录
            System.Xml.XmlElement RecordElement = XmlDoc.CreateElement("Record");
            XmlDoc.DocumentElement.AppendChild( RecordElement );
            for( int iCount = 0 ; iCount < FieldCount ; iCount ++ )
            {
                // 输出一个字段值
                System.Xml.XmlElement FieldElement = XmlDoc.CreateElement( FieldNames[ iCount ] );
                RecordElement.AppendChild( FieldElement );
                object v = reader.GetValue( iCount );
                if( v == null || DBNull.Value.Equals( v ))
                {
                    FieldElement.SetAttribute("Null" , "1" );
                }
                else
                {
                    FieldElement.AppendChild( XmlDoc.CreateTextNode( Convert.ToString( v )));
                }
            }
        }//while( reader.Read())
        reader.Close();
    }//using( System.Data.OleDb.OleDbCommand cmd = conn.CreateCommand())
}//using( System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection())
string strXSLRef = this.Request.QueryString["xsl"] ;
if( strXSLRef != null && strXSLRef.Length > 0 )
{
    // 根据页面参数指定的XSLT样式表名称执行XSLT转换
    strXSLRef = this.Server.MapPath( strXSLRef );
    System.Xml.Xsl.XslTransform transform = new System.Xml.Xsl.XslTransform();
    transform.Load( strXSLRef );
    transform.Transform( XmlDoc , null , this.Response.Output , null );
}
else
{
    // 直接输出生成的XML文档
    this.Response.Write( XmlDoc.DocumentElement.OuterXml );
}

    现对该方法的执行过程进行说明。

    首先是创建一个XmlDocument对 象,XmlDocument创建时是一个空的XML文档,没有任何内容,没有根元素,因此第一步就是使用文档对象的AppendChild方法来添加根元 素。在这里我们使用了文档对象的CreateElement函数来创建一个名为Table的XMLElement元素对象。

    各种类型的XML文档对象,包括元素,属性,文本块,注释 等等,都不能直接实例化,只能使用XmlDocument的一系列以Create开头的函数来创建对象实例。创建的XML文档对象是一个个离散的对象,必 须及时的添加到XML文档对象结构中才能真正成为XML文档的一部分。一般的使用XML文档对象或元素对象的AppendChild方法将新创建的XML 文档对象添加到指定对象下面,如此才加入了XML文档结构的大家庭中。

    这种处理模式类似向DataTable添加新的数据行。DataRow本身不能直接实例化,我们首先得使用DataTable 的NewRow创建一个新的DataRow,然后使用DataTable的Rows属性的Add方法向数据表添加刚刚创建的数据行。

    初始化一个XML文档对象后,我们连接数据库,查询数据库获得一个数据读取器,然后遍历查询所得的数据库记录,输出XML文档。

    对每一个数据库记录,首先创建一个 RecordElement对象,添加到XML文档的根节点下,然后遍历数据库记录的每一个字段值,创建一个FieldElement对象并添加到 RecordElement下面,若当前数据库字段值为空,则调用FieldElement的SetAttribute 方法,设置名为Null的属性值为1,否则向FieldElement添加一个XML文本节点。

    完成生成XML文档后,我们就向页面输出XML文档的内容,若页面参数中指定了XSLT转换文档名称则执行XSLT转换,并输出转换结果。关于XSLT下节课程将详细说明。

    若未指明XSLT转换信息,则输出XML文档根节点的外围XML字符串。

    每一个XML文档对象都具有InnerXml属性和 OuterXml属性,这两个属性都直接返回表示该XML文档片断的不带缩进的XML字符串,但两者有差别。InnerXml返回表示该节点所有子孙节点 的XML字符串。而OuterXml返回表示该节点本身和所有子孙节点的XML字符串。例如对于XML文档”<a><b />123</a>”,则它的根节点的InnerXml就是”<b />123”,而它的根节点的OuterXml就是”<a><b />123</a>”。注意这个字符串是不带缩进的。而XML文档直接保存到指定名称的文件中是带缩进的。

    在IE浏览器中查看该页面,可以看到IE只是显示XML文 档中的纯文本内容,并不像显示其他XML文档时的那种带缩进的显示。这是因为该ASPX的代码中没有设置ContentType为XML格式,而是使用默 认的HTML格式,因此IE浏览器接受该页面文档代码,并把它当作HTML进行解析和显示,由于Table,Record等XML名称都不是HTML标 签,因此IE浏览器忽略掉这些XML标记,只显示出其中的纯文本内容。但你查看该页面的源代码,可以看出该文档的内容仍然是标准的XML格式,这里的源代 码没有缩进处理。

原文地址:https://www.cnblogs.com/meilibao/p/2688745.html