3. IIS 5.0与XML

本章重点
 

介绍IIS 5.0与XML,包括ADO如何支援XML、ADO如何支援XML、Internet Explorer 5.0如何支援XML等功能。

其中ADO如何支援XML单元,将介绍Recordset储存成XML档案、Recordset以XML格式输出到浏览器、Recordset以XML格式储存於记忆体、记忆体XML格式资料转到Recordset,为本书精彩的部份。

XML(eXtensible Markup Language)支援
 

XML(eXtensible Markup Language)将成为资料交换的标准。

IIS 5.0於XML(eXtensible Markup Language)支援方面,包含:

  1. ADO支援XML,可以直接将recordset的资料,以XML格式储存成一个XML档案或输出(Response)到浏览器;或将recordset的资料以XML格式储存於记忆体中(使用STREAM物件)。
  2. XML Parser(XMLDOM)以解析XML档案,可於Internet Explorer(client)与ASP(server)上使用。
  3. Internet Explorer 5.0支援XML,包括Internet Explorer 5.0 XML Data Islands和Databinding,以及XSL(eXtensible Stylesheet Language)Stylesheets。

3-1 ADO如何支援XML呢?
 

Windows 2000 Server之IIS 5.0包括ADO 2.5版,IIS 4.0可使用ADO 2.1版。

ADO 2.5对於XML新提供的功能:

  1. 直接将recordset的资料,以XML格式输出(Response)到浏览器,使用RS.Save Response, adPersistXML指令。
  2. 新增加STREAM物件,於记忆体储存XML格式的资料,将ADO之Recordset资料储存成XML格式,暂时放置於记忆体当中,提供recordset与记忆体XML格式资料之间的交换功能。

ADO支援XML,可以直接将recordset的资料,以XML格式储存成一个XML档案或输出(Response)到浏览器;或将recordset的资料以XML格式储存於记忆体中(使用STREAM物件)。包括:

  1.  Recordset储存成XML档案: ADO 2.1版,直接将recordset的资料,以XML格式储存成一个XML档案,使用RS.Save "xxx.xml", adPersistXML指令。
  2.  Recordset以XML格式输出到浏览器: ADO 2.5版,直接将recordset的资料,以XML格式输出(Response)到浏览器,使用RS.Save Response, adPersistXML指令。
  3.  Recordset以XML格式储存於记忆体: ADO 2.5版,将recordset的资料以XML格式储存於记忆体(使用STREAM物件)中,使用RS.Save ST, adPersistXML指令。
  4.  记忆体XML格式资料转到Recordset: ADO 2.5版,将储存於记忆体(使用STREAM物件)中XML格式资料转到recordset中,使用RS.Open ST指令。

STREAM物件
 

STREAM物件,用於储存XML格式资料於记忆体中,可使用以下方法:

  •  rs.Save st, adPersistXML: 将recordset的资料以XML格式使用STREAM物件储存於记忆体中。
     
  •  Response.Write st.ReadText: 将STREAM物件储存於记忆体中之XML资料输出(Response)到浏览器中。
     
  •  st.Open: 开启STREAM物件。
     
  •  st.WriteText objTextStream.ReadAll(): 将文字字串储存於STREAM物件记忆体中。
     
  •  st.Position = 0: 将指标指到STREAM物件记忆体起点。
     
  •  rs.Open st: 将储存於STREAM物件记忆体中之XML格式资料转到recordset中。
     

Recordset储存成XML档案
 

於IIS 4.0之ADO 2.1版(当然可用於IIS 5.0之ADO 2.5版),使用RS.Save "xxx.xml", adPersistXML指令,即可直接将recordset的资料,以XML格式储存成一个XML档案。

譬如asp程式码xmlado1.asp,如下:

<%
Set conn1 = Server.CreateObject("ADODB.Connection")
conn1.Open "DBQ="& Server.MapPath("test.mdb")& ";Driver=
{Microsoft Access Driver(*.mdb)};"
set RS = Server.CreateObject( "ADODB.Recordset" ) 
RS.Open "select * from PRODUCT", conn1 
RS.Save Server.MapPath("test1.xml"), 1 'adPersistXML 
rs.close
conn1.close 
Response.Redirect "test1.xml"
%>

将test.mdb中PRODUCT资料表的资料先开启於recordset RS中,再使用RS.Save "test1.xml", adPersistXML指令,以XML格式储存成一个XML档案test1.xml,最後重新导向到此新产生的XML档案。

於浏览器执行结果如下,显示此新产生的XML档案:


 

又譬如asp程式码xmlado2.asp,如下:

<%
Set conn1 = Server.CreateObject("ADODB.Connection")
conn1.Open "DBQ="& Server.MapPath("test.mdb")& ";Driver=
{Microsoft Access Driver(*.mdb)};"
set RS = Server.CreateObject( "ADODB.Recordset" )
RS.Open "select * from PRODUCT", conn1 
strFilename = Server.MapPath("test1.xml") 
RS.Save strFilename, 1 'adPersistXML 
set objFS = Server.CreateObject("Scripting.
FileSystemObject")
set objTextStream = objFS.OpenTextFile(strFilename, 1) 
Response.Write objTextStream.ReadAll()	
objTextStream.Close()
rs.close
conn1.close
    %>

使用Scripting.FileSystemObject,读取所新产生的XML档案,於浏览器执行之结果同上例。

Recordset以XML格式输出到浏览器
 

於IIS 5.0之ADO 2.5版,使用RS.Save Response, adPersistXML指令,即可直接将recordset的资料,以XML格式输出(Response)到浏览器。

譬如asp程式码xmlado3.asp,如下:

<%
Response.ContentType = "text/xml"
Response.Expires = 0
%>
<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<%
Set conn1 = Server.CreateObject("ADODB.Connection")
conn1.Open "DBQ="& Server.MapPath("test.mdb")& ";Driver=
{Microsoft Access Driver(*.mdb)};"
set objRS = Server.CreateObject( "ADODB.Recordset" )
objRS.Open "select * from PRODUCT", conn1 
if Request.ServerVariables("SERVER_SOFTWARE")= "Microsoft-IIS/5.0" then
	objRS.Save Response, 1   'adPersistXML 
else
	dim objFS, strFilename, strTempFolder, objTextStream
	set objFS = Server.CreateObject( "Scripting.
FileSystemObject" )
	strTempFolder = objFS.GetSpecialFolder( TemporaryFolder 
)+ "\"
	strFilename = objFS.GetTempName()
	objRS.Save strTempFolder + strFilename, 1 'adPersistXML 
	set objTextStream = objFS.OpenTextFile(strTempFolder 
+ strFilename, 1)
	Response.Write objTextStream.ReadAll()	
	objTextStream.Close()
	objFS.DeleteFile strTempFolder + strFilename, False
end if
%>

将test.mdb中PRODUCT资料表的资料先开启於recordset RS中,再使用RS.Save Response, adPersistXML指令,直接将recordset的资料,以XML格式输出(Response)到浏览器。

其中使用Request.ServerVariables("SERVER_SOFTWARE")判断是否使用IIS 5.0("Microsoft-IIS/5.0"),若是,则使用RS.Save Response, adPersistXML指令;若不是,则使用objRS.Save "XXX.XML", adPersistXML先储存到暂时的XML档案,再使用objTextStream.ReadAll()读取XML档案所有资料并使用Response.Write显示出来。

於浏览器执行xmlado3.asp结果如下,显示输出(Response)到浏览器之画面:


 

Recordset以XML格式储存於记忆体
 

於IIS 5.0之ADO 2.5版,使用RS.Save ST, adPersistXML指令,即可将recordset的资料以XML格式储存於记忆体(使用STREAM物件)中。

譬如asp程式码xmlado4.asp,如下:

<%
Response.ContentType = "text/xml"
Response.Expires = 0
%>
<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<%
Set conn1 = Server.CreateObject("ADODB.Connection")
conn1.Open "DBQ="& Server.MapPath("test.mdb")& ";Driver=
{Microsoft Access Driver(*.mdb)};"
set rs = Server.CreateObject( "ADODB.Recordset" )
rs.Open "select * from PRODUCT", conn1 
' ADOToXML
	set  st = Server.CreateObject( "ADODB.Stream" )        
	rs.Save st, 1	'adPersistXML
	Response.Write st.ReadText
%>

将test.mdb中PRODUCT资料表的资料先开启於recordset RS中,再使用RS.Save ST, adPersistXML指令,即可将recordset的资料以XML格式储存於记忆体(使用STREAM物件)中,使用st.ReadText读取记忆体所有XML资料并经过Response.Write显示出来。

於浏览器执行结果如下,显示此所有XML资料:


 

记忆体XML格式资料转到Recordset
 

於IIS 5.0之ADO 2.5版,使用RS.Open ST指令,即可将储存於记忆体(使用STREAM物件)中XML格式资料转到recordset中。

譬如asp程式码xmlado5.asp,如下:

<%
	set objFS = Server.CreateObject("Scripting.
FileSystemObject")
	xmlfile = Server.MapPath("test.xml")
	set objTextStream = objFS.OpenTextFile(xmlfile, 1) 
   set rs = Server.CreateObject( "ADODB.Recordset" )
   set st = Server.CreateObject( "ADODB.Stream" )
    
    	st.Open
    	st.WriteText objTextStream.ReadAll()
    	st.Position = 0
    	rs.Open st
%> <TABLE BORDER=1>
	<% Do While Not RS.EOF %>
	<TR>
	<% For i = 0 to RS.Fields.Count - 1 %>
		<TD BGCOLOR="f7efde" VALIGN=TOP><FONT 
COLOR="#0000"><% = RS(i)%></FONT></TD>
	<% Next %>
	</TR>
	<%
	RS.MoveNext
	Loop
	RS.Close
	%>
	</TABLE>

首先使用Scripting.FileSystemObject读取XML档案,再使用st.WriteText objTextStream.ReadAll()储存於记忆体(使用STREAM物件)中,然後使用RS.Open ST指令,即可将储存於记忆体(使用STREAM物件)中XML格式资料转到recordset中,最後使用RS(i)於浏览器显示出来。

於浏览器执行结果如下,显示此XML档案资料:


 

中文部份显示成乱码,请读者试试是否可以解决。

3-2 XML Parser如何解析XML档案呢?
 

XML Parser(XMLDOM)用以解析XML档案,可於Internet Explorer(client)与ASP(server)上使用。

载入XML档案
 

载入XML档案时,XML Parser可使用的属性与方法如下:

  •  Load方法: 载入一个XML档案。
     
  •  xml: 可取得XML档案所有内容。
     
  •  parseError.errorCode: 可以得知是否载入错误。
     
  •  parseError.Line: 得知错误解析行数。
     
  •  parseError.errorCode: 得知错误码,若不等於0表示有错误。
     
  •  parseError.reason: 得知错误解析原因。
     
  •  parseError.Line: 得知错误解析行数。
     
  •  parseError.srcText: 得知错误解析文字。
     

譬如asp程式码xmldom1.asp,如下:

<%
'create the XML doc
Set xmlDoc = CreateObject("Microsoft.XMLDOM") 
'load the XML doc
XMLFile = Server.MapPath("books0.xml")
xmlDoc.Load(XMLFile)
Response.Write "<BR>xmlDoc.parseError.errorCode = " & xmlDoc.parseError.errorCode 
Response.Write "<BR>xmlDoc.parseError.Line = " & xmlDoc.parseError.Line
Response.Write "<BR>xmlDoc.parseError.reason = " & xmlDoc.parseError.reason
Response.Write "<BR>xmlDoc.parseError.srcText = " & xmlDoc.parseError.srcText 
Response.Write "<BR>xmlDoc.xml = " & xmlDoc.xml
%>

於浏览器执行xmldom1.asp的结果:


 

首先使用Set xmlDoc = CreateObject("Microsoft.XMLDOM")指令,以使用XML Parser,再使用Load方法以载入一个XML档案,由parseError.errorCode可以得知是否载入错误,若有错误,由parseError.Line得知错误解析行数,由parseError.reason得知错误解析原因,由parseError.Line得知错误解析行数,由parseError.srcText得知错误解析文字。

载入後,由xmlDoc.xml可取得XML档案所有内容。

其中所载入的books0.xml档案之内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<bookstore> <book genre="网站设计">
    <title>ASP网站热门应用技术</title>
    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>
    <price>580</price>
    <publisher>华彩</publisher>
  </book>
  <book genre="网站设计">
    <title>微软热门Web技术速成班</title>
    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>
    <price>450</price>
    <publisher>松岗</publisher>
  </book>
  <book genre="网页设计">
    <title>动态网页设计99招PART 2</title>
    <title>动态网页设计99招PART 3</title>

    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>
    <price>430</price>
    <publisher>第叁波</publisher>
  </book>
</bookstore>

解析XML档案
 

解析XML档案时,XML Parser可使用的属性与方法如下:

  •  selectSingleNode("xxx"): 由此点往下找寻名称为xxx的单一节点。
     
  •  selectNodes("yyy"): 由此点往下找寻所有名称为yyy的节点。
     
  •  length: 节点数目。
     
  •  Attributes.getNamedItem("zzz"): 某一节点Attribute为zzz的值,譬如「<book genre="网页设计">」"中genre之Attributes.getNamedItem("genre")值为"网页设计"。
     
  •  nodeTypedValue: 某一节点的值。
     

譬如asp程式码xmldom1.asp,如下:

<%
'get the node
Set xml_node = xmlDoc.selectSingleNode("bookstore") 
'find the book nodes
Set xml_subNodes = xml_node.selectNodes("book") 
Response.Write "<BR>xml_subNodes.length = " & xml_subNodes.length
For i = 0 To xml_subNodes.length - 1 
	'find the genre attribute and get the value
    	Set xml_subNode = xml_subNodes(i).Attributes.getNamedItem("genre")
 	Response.Write "<P>genre = " & xml_subNode.nodeValue 
   	 'find the title nodes
    	Set xml_subNode = xml_subNodes(i).selectNodes("title") 
   	 'iterate through the node list
    	For j = 0 To xml_subNode.length - 1
 		Response.Write "<BR> title= " & xml_subNode(j).nodeTypedValue
    	Next 
   	 'find the author nodes
    	Set xml_subNode1 = xml_subNodes(i).selectSingleNode("author") 
   	'find the first-name nodes
    	Set xml_subNode2 = xml_subNode1.selectSingleNode("first-name")
	firstname =  xml_subNode2.nodeTypedValue 
   	 'find the last-name nodes
    	Set xml_subNode2 = xml_subNode1.selectSingleNode("last-name")
	lastname = xml_subNode2.nodeTypedValue
 	Response.Write "<BR> author = " & lastname & firstname 
   	 'find the publisher nodes
    	Set xml_subNode = xml_subNodes(i).selectSingleNode("publisher")
 	Response.Write "<BR> publisher = " & xml_subNode.nodeTypedValue 
   	 'find the price nodes
    	Set xml_subNode = xml_subNodes(i).selectSingleNode("price")
 	Response.Write "<BR> price = " & xml_subNode.nodeTypedValue
Next
%>

於浏览器执行结果如下:


 

首先使用selectSingleNode("bookstore")由起点往下找寻名称为bookstore的单一节点,接着使用selectNodes("book")由此点往下找寻所有名称为book的节点。

由length得知找到的节点数目。

然後由Attributes.getNamedItem("genre")取得此节点Attribute为genre的值。

再由selectNodes("title")找寻名称为title的节点,接着由nodeTypedValue取得此节点的值。依序由找寻名称为author、first-name、last-name、publisher、price节点的值。

由For i = 0 To xml_subNodes.length - 1...Next取得所有book节点的值。

新增加节点
 

新增加XML档案的节点时,XML Parser可使用的属性与方法如下:

  •  loadXML("yyy″): 新增加XML标记"yyy″。
     
  •  createElement("xxx"): 新增加名称为xxx的XML节点。
     
  •  documentElement.appendChild(xml_node): 将新增加的节点加入XML文件。
     
  •  documentElement.lastChild: 移到最後节点处。
     
  •  createAttribute("zzz"): 新增加名称为zzz的Attribute。
     
  •  Text: 设定Attribute的值。
     
  •  Attributes.setNamedItem(xml_node): 将新增加的Attribute加入XML文件。
     

譬如asp程式码xmldom2.asp,如下:

<%
'create the XML doc
Set xmlDoc = CreateObject("Microsoft.XMLDOM") 
'load the XML doc
XMLFile = Server.MapPath("log.xml")
xmlDoc.Load(XMLFile) 
'check if xml exists in the file
If xmlDoc.xml = "" Then
	Call xmlDoc.loadXML("<root></root>")
End If 
'create the new log node
Set xml_node = xmlDoc.createElement("log") 
'add the node to the document
Set xml_node = xmlDoc.documentElement.appendChild(xml_node) 
'get the new node
Set xml_logNode = xmlDoc.documentElement.lastChild            
'create the new user atribute
Set xml_node = xmlDoc.createAttribute("User")
xml_node.Text = "jack"       
'add the attribute to the list
Call xml_logNode.Attributes.setNamedItem(xml_node) 
'create the new date atribute
Set xml_node = xmlDoc.createAttribute("Date")
xml_node.Text = CStr(date)       
'add the attribute to the list
Call xml_logNode.Attributes.setNamedItem(xml_node) 
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreatetextFile(XMLFile, True)
a.Write xmlDoc.xml
a.Close 
Response.Redirect "log.xml"
%>

於浏览器执行结果如下,显示此新产生的XML档案:


 

首先使用Set xmlDoc = CreateObject("Microsoft.XMLDOM")指令,以使用XML Parser,再使用Load方法以载入一个XML档案log.xml,若xmlDoc.xml为空字串表示无内容,则由xmlDoc.loadXML("<root></root>")加入<root></root>标记。

接着由xmlDoc.createElement("log")以新增加名称为log的XML节点,由documentElement.appendChild(xml_node)将新增加的节点加入XML文件,再由documentElement.lastChild移到最後节点处以再增加新的节点。

由createAttribute("User")新增加名称为User的Attribute,由Text设定Attribute的值,由Attributes.setNamedItem(xml_node)将新增加的Attribute加入XML文件。

依序加入User、Date的Attribute。

最後使用Scripting.FileSystemObject之CreatetextFile方法,将此XML文件储存成一个XML档案test1.xml,最後Response.Redirect重新导向到此新产生的XML档案。

3-3 Internet Explorer 5.0如何支援XML呢?
 

Internet Explorer 5.0支援XML,包括Internet Explorer 5.0 XML Data Islands和Databinding,以及XSL(eXtensible Stylesheet Language)Stylesheets。

Databinding
 

将XML资料透过DSO(Data Source Object),可将资料Databinding到html标记码上。方法如下:

  •  datasrc: 定义资料来源。
     
  •  datafld: 定义栏位。
     

使用<xml src="booksorder.xml">方法以载入一个XML档案booksorder.xml,如下:

<xml src="booksorder.xml" id="xmldso1" JavaDSOCompatible="true"></xml>

接着於<table>中由datasrc定义资料来源为刚才定义之DSO,如下:

<table ...datasrc="#xmldso1">

每一个<span>中由datafld定义栏位为TITLE、AUTHOR、PUBLISHER、PRICE、QUANTITY,如下:

<table id="table" border="1" datasrc="#xmldso1"> 
...
<td valign="top"><span datafld="TITLE" dataformatas="HTML"></span></td> 
<td valign="top"><span datafld="AUTHOR" dataformatas="HTML"></span></td> ...

譬如HTML程式码ie5xml1.htm,如下:

<table id="table" border="1" datasrc="#xmldso1"> 
<thead align="left"> 
	<th>Title</th> 
	<th>Author</th> 
	<th>Publisher</th> 
	<th>Price</th> 
	<th>Qty</th> 
</thead> 
<tr> 
  <td valign="top"><span datafld="TITLE"></span></td> 
  <td valign="top"><span datafld="AUTHOR"></span></td> 
  <td valign="top"><span datafld="PUBLISHER"></span></td> 
  <td valign="top" align="right"><span datafld="PRICE"></span></td> 
  <td valign="top" align="right"><span datafld="QUANTITY"></td> 
 </tr> 
</table>  
 <A Href="booksorder.xml" Target="_blank">XML Data</A> 
<xml src="booksorder.xml" id="xmldso1" JavaDSOCompatible="true"></xml>

於浏览器执行结果,如下:


 

其中所载入的booksorder.xml档案内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<booksorder> <book genre="网站设计">
    <TITLE>ASP网站热门应用技术</TITLE>
    <AUTHOR>周世雄</AUTHOR>
    <QUANTITY>12</QUANTITY>
    <PRICE>580</PRICE>
    <PUBLISHER>华彩</PUBLISHER>
  </book>
  <book genre="网站设计">
    <TITLE>微软热门Web技术速成班</TITLE>
    <AUTHOR>周世雄</AUTHOR>
    <QUANTITY>10</QUANTITY>
    <PRICE>450</PRICE>
    <PUBLISHER>松岗</PUBLISHER>
  </book>
...
</booksorder>

又譬如HTML程式码ie5xml2.htm,如下:

<html>
<table id="table" datasrc="#xmldso1"> 
<tr><td valign="top"><div datafld="TITLE" dataformatas="HTML"></div></td></tr> 
<tr><td valign="top"><div datafld="AUTHOR" dataformatas="HTML"></div></td></tr> 
<tr><td valign="top"><div datafld="PUBLISHER" dataformatas="HTML"></div></td></tr> 
<tr><td valign="top"><div datafld="PRICE"></div></td></tr> 
<tr><td valign="top"><div datafld="QUANTITY"></div></td></tr> 
<tr><td ><hr/></td></tr> 
</table>  
 <A Href="booksorder.xml" Target="_blank">XML Data</A> 
<xml src="booksorder.xml" id="xmldso1" JavaDSOCompatible="true"></xml>
</html>

於浏览器执行结果如下:


 

每一个<DIV>中由datafld定义栏位为TITLE、AUTHOR、PUBLISHER、PRICE、QUANTITY。

阶层式XML
 

Internet Explorer 5.0也支援阶层式XML,譬如XML档案booksorder3.xml内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<ALLORDERID>
<ORDER>
<ORDERID>010314</ORDERID>
<ITEM> <ProductName>ASP网站热门应用技术 </ProductName>
    <Quantity>6</Quantity>
    <UnitPrice>580</UnitPrice>  
</ITEM>
<ITEM> <ProductName>微软热门Web技术速成班</ProductName>
    <Quantity>6</Quantity>
    <UnitPrice>450</UnitPrice>  
</ITEM>
</ORDER>
<ORDER>
<ORDERID>010529</ORDERID>
<ITEM> <ProductName>动态网页设计99招PART 2</ProductName>
    <Quantity>6</Quantity>
    <UnitPrice>430</UnitPrice>  
</ITEM>
</ORDER>
<ORDER>
<ORDERID>010212</ORDERID>
<ITEM> <ProductName>微软热门Web技术速成班</ProductName>
    <Quantity>2</Quantity>
    <UnitPrice>450</UnitPrice>  
</ITEM>
<ITEM> <ProductName>ASP网站热门应用技术 </ProductName>
    <Quantity>9</Quantity>
    <UnitPrice>580</UnitPrice>  
 </ITEM>
</ORDER> ...
</ALLORD]ERID>

让我们看一个例子,譬如HTML程式码ie5xml6.htm,如下:

<html> 
<table datasrc="#xmldso"> 
<tr> 
<td>ORDERID: <span datafld="ORDERID"></span></td> 
</tr> 
<tr><td> 
<table class="order" border="1" datasrc="#xmldso" datafld="ITEM"> 
<thead><th>产品</th><th>价格</th><th>数量</th></thead> 
<tr><td><span datafld="ProductName"></span></td> 
<td><span datafld="UnitPrice"></span></td> 
<td><span datafld="Quantity"></span></td> 
</tr> 
</table> 
</td></tr>
</table> 
<xmp id="error"></xmp> 
<A Href="booksorder3.xml" Target="_blank">XML Data</A> 
<xml src="booksorder3.xml" id="xmldso"  JavaDSOCompatible="true"></xml> 
</html>

使用<xml src="booksorder3.xml">方法以载入一个XML档案booksorder3.xml,接着於<table>中由datasrc定义资料来源为刚才定义之DSO,<span>中由datafld定义栏位为ORDERID;再於所包括的<table>中由datasrc定义资料来源为刚才定义之DSO,每一个<span>中由datafld定义栏位为ProductName、UnitPrice、Quantity。

於浏览器执行ie5xmll6.htm结果如下:


 

Recordset
 

将XML资料透过DSO(Data Source Object),可以将资料Databinding到html标记码上,Data Source Object可使用Recordset方法如下:

  •  rs.MoveNext(): 移到下一笔资料。
     
  •  rs.MovePrevious(): 移到上一笔资料。
     
  •  rs.MoveFirst(): 移到第一笔资料。
     
  •  rs.MoveLast(): 移到第末笔资料。
     
  •  rs.("栏位名称″): 栏位值。
     
  •  rs.AddNew(): 新增。
     
  •  rs.Update(): 修改。
     
  •  rs.Delete(): 删除。
     

譬如於浏览器执行ie5xml3.htm结果如下:


 

ie5xml3.htm之HTML程式码,如下:

<html>
<table id="table" border="1" datasrc="#xmldso1"> 
<thead align="left"> 
	<th>Title</th> 
	<th>Author</th> 
	<th>Publisher</th> 
	<th>Price</th> 
	<th>Qty</th> 
</thead> 
<tr> 
  <td valign="top"><span datafld="TITLE" dataformatas="HTML"></span></td> 
  <td valign="top"><span datafld="AUTHOR" dataformatas="HTML"></span></td> 
  <td valign="top"><span datafld="PUBLISHER" dataformatas="HTML"></span></td> 
  <td valign="top" align="right"><span datafld="PRICE"></span></td> 
  <td valign="top" align="right"><input type="text" size="10" datafld="QUANTITY" 
  dataformatas="HTML" onblur="DoCalc();"/></td>  
</tr> 
<tfoot> 
	<th></th> 
	<th></th> 
	<th></th> 
	<th align="right">Total</th> 
	<th><span id="total"></span></th> 
</tfoot> 
</table>  
<xmp id="error"></xmp> 
 
<A Href="booksorder.xml" Target="_blank">XML Data</A>  
<xml src="booksorder.xml" id="xmldso1" JavaDSOCompatible="true"></xml>    
<script>  
function DoCalc() 
{  
    doc = xmldso1.XMLDocument;  
    if(doc.documentElement == null) 
        error.innerText = doc.parseError.reason;  
    else  
{  
    var rs = xmldso1.recordset;  
    rs.MoveFirst();  
    var t= 0;  
    while(! rs.eof) 
    {  

        t+= rs("QUANTITY")* rs("PRICE");  
        rs.MoveNext();  
    }  
    t = parseInt(t*100)/100;  
    tspan = document.all("total");  
    if(tspan) 
    {  
        tspan.innerText = t;  
    }  
    return t;  
}  
}  
  
</script>    
</html>

当於Qty栏位输入後,离开时将执行DoCalc()函数,使用rs.MoveFirst()方法移到第一笔资料和rs.MoveNext()方法移到下一笔资料,由rs("QUANTITY")* rs("PRICE")以计算总和。

<object...>
 

除了如上例直接由<xml src=...>载入一个XML档案的方法外,也可以使用DSO(Data Source Object)ActiveX Control和使用doc.load(「booksorder.xml」)方法以载入一个XML档案。

使用DSO(Data Source Object)ActiveX Control方法以载入一个XML档案booksorder.xml,如下:

<object width="0" height="0" classid="clsid:550dda30-0541-
11d2-9ca9-0060b0ec3d39" id="xmldso1" ></object>
<script for="window" event="onload"> xmldso1.
JavaDSOCompatible = true;
    var doc = xmldso1.XMLDocument;
    doc.load("booksorder.xml");
    if(doc.parseError.errorCode != 0)
        error.innerText = doc.parseError.reason;
</script>

让我们再看一个例子,譬如HTML程式码ie5xmll4.htm,如下:

<html>
<body>
<object width="0" height="0" classid="clsid:550dda30-0541-
11d2-9ca9-0060b0ec3d39" id="xmldso1" >
</object> 
<script for="window" event="onload"> xmldso1.
JavaDSOCompatible = true;
    var doc = xmldso1.XMLDocument;
    doc.load("booksorder.xml");
    if(doc.parseError.errorCode != 0)
        error.innerText = doc.parseError.reason;
</script> 
<table>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="TITLE"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="AUTHOR"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="PUBLISHER"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="PRICE"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="QUANTITY"></div></td></tr>
<tr><td ><hr/></td></tr>
</table> 
<xmp id="error"></xmp>
<button onclick="xmldso1.recordset.moveprevious();">上一
笔</button>
<button onclick="xmldso1.recordset.movenext();">下一笔</
button>
<A Href="booksorder.xml" Target="_blank">XML Data</A>
</body>
</html>

於浏览器执行ie5xmll4.htm结果如下:


 

按下 下一笔 按钮时,显示下一笔资料如下:


 

说明如下,首先使用一个XML之DSO(Data Source Object)ActiveX Control,如下:

<object width="0" height="0" classid="clsid:550dda30-0541-
11d2-9ca9-0060b0ec3d39" id="xmldso1" >
</object>

var doc = xmldso1.XMLDocument定义doc为刚才DSO之XML文件,以使用XML Parser,再使用doc.load("booksorder.xml")方法以载入一个XML档案booksorder.xml,由parseError.errorCode可以得知是否载入错误,若有错误,由parseError.errorCode得知错误码,若不等於0表示有错误,parseError.reason得知错误原因。

接着於每一个<div>中由datasrc定义资料来源为刚才定义之DSO,由datafld定义栏位为TITLE、AUTHOR、PUBLISHER、PRICE、QUANTITY,如下:

<table>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="TITLE"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="AUTHOR"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="PUBLISHER"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1"
 datafld="PRICE"></div></td></tr>
<tr><td valign="top"><div datasrc="#xmldso1" 
datafld="QUANTITY"></div></td></tr>
<tr><td ><hr/></td></tr>
</table>

即可显示一笔XML资料。

按下 下一笔 按钮时,使用recordset.movenext()方法,显示下一笔资料;按下 上一笔 按钮时,使用recordset.moveprevious()方法,显示上一笔资料,如下:

<button onclick="xmldso1.recordset.moveprevious();">上一
笔</button>
<button onclick="xmldso1.recordset.movenext();">下一笔</
button>

新增修改删除
 

让我们再看一个新增修改删除的例子,譬如HTML程式码ie5xmll5.htm,如下:

<html>
<table border="2" cellpadding="3" align="left" 
bordercolordark="#000000" bordercolorlight="#C0C0C0"> 
<tr><td width="100"><b>TITLE</b></td> 
<td><input type="text" size="50" 
datasrc="#xmldso" datafld="TITLE"/></td> 
</tr><tr><td width="100"><b>AUTHOR</b></td> 
<td><input type="text" size="50" datasrc="#xmldso" datafld="AUTHOR"/></td> 
</tr><tr><td width="100"><b>PUBLISHER</b></td> 
<td><input type="text" size="50" datasrc="#xmldso" datafld="PUBLISHER"/></td> 
</tr><tr><td width="100"><b>PRICE</b></td> 
<td><input type="text" size="50" datasrc="#xmldso" datafld="PRICE" /></td> 
</tr><tr><td width="100"><b>QUANTITY</b></td> 
<td><input type="text" size="50" datasrc="#xmldso" datafld="QUANTITY" /></td> 
</tr> 
</table>  
<br clear="all"/>  
<button onclick="xmldso.recordset.movefirst();">第一笔</
button> 
<button onclick="xmldso.recordset.moveprevious();">上一笔
</button> 
<button onclick="xmldso.recordset.movenext();">下一笔</
button> 
<button onclick="xmldso.recordset.movelast();">最末笔</
button> 
<button onclick="xmldso.recordset.AddNew();">新增</button> 
<button onclick="xmldso.recordset.Update();">修改</button> 
<button onclick="xmldso.recordset.Delete();">删除</button> 
<xmp id="error"></xmp> 
<A Href="booksorder.xml" Target="_blank">XML Data</A> 
<xml src="booksorder.xml" id="xmldso" JavaDSOCompatible="true"></xml> 
</html>

於浏览器执行ie5xmll5.htm结果如下:


 

按下 第一笔  上一笔  下一笔  最末笔  新增  修改  删除 按钮时,使用movefirst()、moveprevious()、movenext()、movelast()、AddNew()、Update()、Delete()方法,如下:

<button onclick="xmldso.recordset.movefirst();">第一笔</button> 
<button onclick="xmldso.recordset.moveprevious();">上一笔</button> 
<button onclick="xmldso.recordset.movenext();">下一笔</button> 
<button onclick="xmldso.recordset.movelast();">最末笔</button> 
<button onclick="xmldso.recordset.AddNew();">新增</button> 
<button onclick="xmldso.recordset.Update();">修改</button> 
<button onclick="xmldso.recordset.Delete();">删除</button>

Data Islands范例
 

Internet Explorer 5.0支援Data Islands,可於数个XML档案中切换资料,譬如XML档案books2.xml,内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<bookstore> <book genre="网站设计">
    <title>ASP网站热门应用技术</title>
    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>
    <price>580</price>
    <publisher>华彩</publisher>
  </book>
  <book genre="网站设计">
    <title>微软热门Web技术速成班</title>
    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>
    <price>450</price>
    <publisher>松岗</publisher>
  </book>
  <book genre="网页设计">
    <title>动态网页设计99招PART 2</title>
    <title>动态网页设计99招PART 3</title>
    <author>
      <first-name>世雄</first-name>
      <last-name>周</last-name>
    </author>

    <price>430</price>
    <publisher>第叁波</publisher>
  </book> 
</bookstore> XML档案

books3.xml内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<xml>
<book> <title>动态网页设计99招PART 2</title>
    <author>周世雄</author>
    <price>430</price>
    <publisher>第叁波</publisher>
  </book>
<book> <title>动态网页设计99招PART 3</title>
    <author>周世雄</author>
    <price>430</price>
    <publisher>第叁波</publisher>
  </book>
</xml>

让我们看一个例子,譬如HTML程式码xmlDataIslands1.htm,如下:

选择


<XML ID=xmlData></XML> 
<SCRIPT LANGUAGE=JavaScript> 
function generateHTML(path){
		// Set the src property of the XML data island
		xmlData.src = path; 
		// Instruct the XML data island to use synchronous data transfer
		xmlData.async = false;	
	var strHTML = "<TABLE><THEAD><TH>title</TH><TH>author
</TH><TH>price</TH><TH>publisher</TH></THEAD><TBODY>";
	var book = xmlData.selectNodes( "//book" );	
	for( var i = 0; i < book.length; i++ ){ 
		strHTML += "<TR>";
		strHTML += "<TH>" + book.item( i ).selectSingleNode
( "title" ).text + "</TH>";
		strHTML += "<TD>" + book.item( i ).selectSingleNode
( "author" ).text + "</TD>";		
		strHTML += "<TD>" + book.item( i ).selectSingleNode
( "price" ).text + "</TD>";		
		strHTML += "<TD>" + book.item( i ).selectSingleNode
( "publisher" ).text + "</TD>";
		strHTML += "</TR>";
	}	
	strHTML += "</TBODY></TABLE>";
	divOutput.innerHTML = strHTML ;
} 
</SCRIPT>     
<INPUT TYPE=button VALUE="网站设计" onClick="generateHTML
('books2.xml')">
<INPUT TYPE=button VALUE="网页制作" onClick="generateHTML
('books3.xml')"> 
<DIV ID=divOutput></DIV> 
</BODY>
</HTML>

於浏览器执行xmlDataIslands1.htm结果如下:


 

可於2个XML档案中切换资料。

综合范例
 

举一个综合范例,譬如XML档案booksorder2.xml,内容如下:

<?xml version="1.0" encoding="BIG5" standalone="yes" ?> 
<XML xmlns:dt="urn:schemas-microsoft-com:datatypes">
<CUSTOMER>
<NAME>王子庆</NAME>
<ORDER>
<OrderID>010314</OrderID>
<OrderDate>03/14/2001</OrderDate>
<ITEM> <ProductName>ASP网站热门应用技术 </ProductName>
    <Quantity>6</Quantity>
    <UnitPrice dt:dt="fixed.14.4">580</UnitPrice>  
 </ITEM>
<ITEM> <ProductName>微软热门Web技术速成班</ProductName>
    <Quantity>6</Quantity>
    <UnitPrice dt:dt="fixed.14.4">450</UnitPrice>  
 </ITEM>
</ORDER>
<ORDER>
<OrderID>010529</OrderID>
<OrderDate>05/29/2001</OrderDate>
<ITEM> <ProductName>动态网页设计99招PART 2</ProductName>
    <Quantity>6</Quantity>
    <UnitPrice dt:dt="fixed.14.4">430</UnitPrice>  
 </ITEM>
</ORDER>
</CUSTOMER> ...
</XML>

综合范例HTML程式码ie5xmll7.htm,如下:

<html>
<table> 
<tr><td> 
<table datasrc="#xmldso"> 
<tr><td>客户: <span datafld="NAME"></span> 
<table datasrc="#xmldso" datafld="ORDER"> 
<tr onMouseOver="mousemove('over',this)" onMouseOut="mousemove
('out',this)" onclick="SelectCell(this)"> 
<td class="customer" ><span datafld="OrderID"></span></td> 
<td class="customer"><span datafld="OrderDate"></span></td> 
</tr> 
</table>
</td></tr>    		 
</table> 
<table class="order" border="1" datasrc="#xmldso2"> 
<thead><th>产品</th><th>价格</th><th>数量</th></thead> 
 <tr><td><span datafld="ProductName"></span></td> 
<td><span datafld="UnitPrice"></span></td> 
<td><span datafld="Quantity"></span></td> 
</tr> 
</table> 
<xmp id="error"></xmp> 
<A Href="booksorder2.xml" Target="_blank">XML Data</A> 
 
<object width="0" height="0" classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39" 
id="xmldso" > 
</object> 
<object width="0" height="0" classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39" 
id="xmldso2"> 
</object> 
<script for="window" event="onload"> 
    xmldso.JavaDSOCompatible = true; 
    xmldso2.JavaDSOCompatible = true; 
    var doc = xmldso.XMLDocument; 
    doc.load("booksorder2.xml"); 
    if(doc.parseError.errorCode != 0)
        error.innerText = doc.parseError.reason; 
</script> 
<script> 
    var selectedRow; 
    function ColorCells(row,color)
    { 
        var cells = row.cells; 
        var len = cells.length; 
        for(i = 0; i < len; i++)
            cells(i).style.backgroundColor = color; 
    } 
    function mousemove(which, e)
    { 
        var e; 
        var color =((which == "over")? "yellow" : "");  
        e = window.event.srcElement; 
        while(e.tagName != "TR" && e.tagName != "TABLE")
            e = e.parentElement;  
        if(e.tagName == "TR" && e != selectedRow)
            ColorCells(e,color); 
    } 
    function SelectCell(cell)
    { 
        var innerrow = window.event.srcElement; 
        while(innerrow.tagName != "TR")
            innerrow = innerrow.parentElement; 
        var innertable = innerrow; 
        while(innertable.tagName != "TABLE")
            innertable = innertable.parentElement;  
        var outerrow = innertable; 
        while(outerrow.tagName != "TR")
            outerrow = outerrow.parentElement;          
        var outertable = outerrow; 
        while(outertable.tagName != "TABLE")
            outertable = outertable.parentElement;  
        var doc = xmldso.XMLDocument; 
        var root = doc.documentElement; 
        var customer = root.selectNodes("//CUSTOMER").item(outerrow.rowIndex); 
        var order = customer.selectNodes("ORDER").item(innerrow.rowIndex); 
        var xml = ""; 
        var items = order.selectNodes("ITEM"); 

        var item = items.nextNode(); 
        while(item)
        { 
            xml = xml + item.xml; 
            item = items.nextNode(); 
        } 
        xml = "<ORDER>\n" + xml + "\n</ORDER>"; 
        xmldso2.XMLDocument.loadXML(xml); 
        if(selectedRow != null)
        { 
            ColorCells(selectedRow,"");             
        } 
        selectedRow = innerrow; 
        ColorCells(selectedRow,"red"); 
    } 
</script>
</html>

於浏览器执行结果如下:


 

您学会了吗 ?