xml,已成為近來最熱門的web技術,它是sql server 2000中的重要部分。本文將綜合七條sql server 2000中最重要的xml綜合特性組成xml之七種兵器。 
  兵器之一:for xml
  在sql server 2000中,標準的t-sql select語句包括for xml子句,它以xml文檔形式返回一個查詢結果。新的for xml子句有三種模式——raw,auto,和explicit,每個都能對xml文檔格式提供附加標準的控制。
  下面首先介紹“for xml”的使用方法。
  為了從sql server提取xml格式的數據,t-sql中加入了一個for xml命令。在查詢命令中使用for xml命令使得查詢結果以xml格式出現。for xml命令有三種模式:raw,auto和explicit。圖1所顯示的sql命令訪問sql server提供的pubs示例數據庫。有關pubs數據庫的更多信息,請參見msdn說明。如果我們依次指定該sql命令的模式為三種允許的模式之一,就可以得到各種模式所支持的不同xml輸出。 
【圖1 】
select store.stor_id as id, stor_name as name, 
sale.ord_num as orderno,sale.qty as qty
from stores store inner join 
sales sale on store.stor_id = sale.stor_id
order by stor_name
for xml <模式> 
  該查詢命令所生成的結果包含所有銷售記錄及其對應的商店,結果以商店名稱的字母升序排列。查詢的最后加上了for xml命令以及具體的模式,比如for xml raw。 
  理想情況下,sql命令所生成的xml文檔應具有如下結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
</sale orderno=&single;&single; qty=&single;&single;>
</store>
</stores>
  下面我們來看看具體的處理方法。 
  raw模式 
  下面是指定raw模式時結果xml文檔的一個片斷。
  查詢結果集中每一個記錄包含唯一的元素<row>。由于我們無法控制元素名字和文檔結構,因此這種模式不是很有用。raw模式所生成的文檔結構與我們所希望的不符,而且它的用途也非常有限。 
  auto模式 
  下面是指定auto模式時結果文檔的一個片斷: 
  可以看到,<stroe>和<sale>兩個元素是父-子關系,形成了我們所希望的層次結構。這種節點關系由查詢中表的聲明次序決定,后聲明的表成為前聲明表的孩子。 
  再參考圖1,我們可以看出查詢命令所指定的別名決定了xml文檔中的名字。根據這一點,我們可以控制xml文檔元素、屬性的名字,使得這些名字符合我們所要求的命名慣例。 
  可見auto模式能夠創建出我們所需要的xml文檔。不過它存在以下缺點: 
  雖然可以得到層次結構,但這種層次結構是線性的,即每個父節點只能有一個子節點,反之亦然。 
  通過別名指定元素名字不太方便,而且有時候會影響查詢命令本身的可讀性。 
  無法在文檔中同時生成元素和屬性。要么全部是元素(通過elements關鍵詞指定),要么全部是屬性(默認)。 explicit模式解決了上述不足。 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
 explicit模式 
  explicit模式比較復雜,我們將用另外一種方法來表達圖1所顯示的查詢。這種方法使得我們能夠完全地控制查詢所生成的xml文檔。首先我們將介紹如何改用explicit模式編寫圖1所顯示的查詢,然后看看這種方法如何賦予我們遠遠超過auto模式的能力。 
  下面是圖1查詢用explicit模式表達的代碼: 
【圖2 】
--商店數據
select 1 as tag,
null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as[sale!2!orderno],
null as [sale!2!qty]
from stores s
union all
-- 銷售數據
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty
from stores s, sales sa
where s.stor_id = sa.stor_id
order by [store!1!name]
for xml explicit 
  這個查詢初看起來有點復雜,其實它只是把不同的數據集(即這里的store和sale)分解到了獨立的select語句里,然后再用union all操作符連結成一個查詢。 
  我們之所以要把查詢寫成上面的形式,是為了讓查詢結果不僅包含xml文檔所描述的數據,而且還包含描述xml文檔結構的元數據。上述查詢所生成的表稱為universal表,sqlxml.dll生成xml文檔時需要這種格式。universal表對于編寫代碼的人來說是透明的,但了解這個表還是很有意義的,它將有助于代碼的開發和調試。下面是universal表的一個例子: 
tag parent store!1!id store!1!name sale!2!orderno sale!2!qty
1 null 7066 barnum&single;s null null
2 1 7066 barnum&single;s a297650 50
2 1 7066 barnum&single;s qa7442 375
1 null 8042 bookbeat null null
2 1 8042 bookbeat 423ll9 2215
  universal表和explicit模式查詢的元數據部分都以紅色表示,黑色表示數據。比較查詢和表就可以找出sqlxml.dll生成xml文檔所需要的元素。我們來仔細地分析一下它們描述的是什么。 
  tag和parent列是xml文檔層次結構方面的信息,我們可以認為圖2中的每個select語句代表了一個xml節點,而tag和parent列讓我們指定節點在文檔層次結構中的位置。如果在第二個select語句中指定tag為2、指定parent為1,就表示為這些數據加上了一個值為2的標簽,而這些數據的父親是那些標簽為1的數據(即第一個select語句)。這就使得我們能夠構造出<store>和<sale>之間的父-子關系,而且正如你可能猜想到的,它使得我們可以生成任意合法的xml文檔結構。注意第一個select命令的parent列設置成了null,這表示<store>元素處于最頂層的位置。 
  以黑色表示的數據將成為節點的屬性或元素,例如,store_id就通過列名提供了這方面的信息。列名字中的“!”是分隔符,總共可分成四項(四個參數),其中第四個參數是可選的。這些參數描述的是: 
  第一個參數描述該列所屬元素的名字,在這里是<store>元素。 
  第二個是標簽編號,它指定了該列信息在xml樹形結構中所處位置。 
  第三個參數指定xml文檔內的屬性或元素名字。在這里名字指定為id。 
  數據列默認被創建為參數2所指定節點的屬性,即id將成為<store>節點的屬性。如果要指定id是<store>的一個子元素,我們可以使用第四個可選的參數,這個參數的一個作用就是讓我們把該項指定為元素,例如store!1!id!element。 
  由于使用了union all操作符來連結select語句,為了保證sql查詢的合法性,所有select語句的選擇結果必須具有相同數量的列。我們使用null關鍵詞來補足select語句,從而避免了重復數據。 
  通過explicit模式查詢所生成的xml文檔和通過auto模式生成的完全相同,那么為什么要創建explicit模式查詢呢? 
  假設現在有人要求在xml文檔中包含商店的打折信息。查看pubs數據庫,我們得知每個商店都可以有0到n范圍內的折扣率。因此,一種合理的方法是在<store>元素下面加上子元素<discount>,這樣我們就得到如下xml文檔結構: 
<stores>
<store id=&single;&single; name=&single;&single;>
<discount type=&single;&single; lowqty=&single;&single; highqty=&single;&single;>
<amount></amount>
</discount>
<sale ordno=&single;&single; qty=&single;&single;>
</sale>
</store>
</stores> 
  這里的改動包括: 
  要在<sale>元素所在的層次增加一個xml元素<discount>,即<discount>是<stroe>的子元素。 
  amount嵌套在<discount>里面,但不應該是<discount>元素的屬性。 
  在auto模式中是不可能實現這些改動的。 
  下面是創建這個新xml文檔的explicit模式查詢: 
【圖 2a】
select 1 as tag, null as parent,
s.stor_id as [store!1!id],
s.stor_name as [store!1!name],
null as [sale!2!orderno],
null as [sale!2!1ty],
null as [discount!3!type],
null as [discount!3!lowqty],
null as [discount!3!highqty],
null as [discount!3!amount!element]
from stores s
union all
select 2, 1,
s.stor_id,
s.stor_name,
sa.ord_num,
sa.qty,
null,
null,
null,
null
from stores s, sales sa
where s.stor_id = sa.stor_id
union all
select 3, 1,
null,
s.stor_name,
null,
null,
d.discounttype,
d.lowqty,
d.highqty,
d.discount
from stores s, discounts d
where s.stor_id = d.stor_id
order by [store!1!name]
for xml explicit 
  為了創建圖2a所顯示的explicit模式查詢,我們對圖2的查詢進行了如下修改: 
  增加了第三個子查詢提取折扣數據,通過tag列聲明這些數據的標簽值為3。 
  通過指定parent列為1將折扣數據設置成<store>元素的子元素。 
  注意在第三個select子查詢中我們只包含了那些必需的列,并用null補足空列。這個子查詢包含store_name列,雖然discount元素并不要用到這個列,但如果把這個列也設置為null,則結果universal表將不會按照解析器所要求的那樣以節點升序排序(不妨自己試一下看看)。universal表的排序列也可以用tag列替代。 
  為維持結果universal表的完整性,第一、二兩個select語句也用null補足以反映為折扣數據增加的列。 
  為指定新折扣列的元數據修改了第一個select語句。 
  通過在第四個參數中聲明element指定amount列為discount的一個元素(element是可在第四個參數中聲明的多個指令之一)。 
  下面這個xml文檔只能用explicit模式生成: 
  結果xml文檔中不會顯示出null數據,如折扣lowqty和highqty。
  看來上面的介紹,大家可能已經對for xml的語法有所了解。通過for xml 我們在能夠在query analyzer 中直接返回一個xml格式的數據或者通過其他多樣化表現方式將xml格式的數據顯示出來,比如可以將數據顯示在瀏覽器上。下面這個例子就使用for xml和ado將數據輸出到瀏覽器的例子。
dim adoconn
set adoconn = server.createobject("adodb.connection")
dim sconn
sconn = "provider=sqloledb;data source=192.168.0.160;initial catalog=northwind;user id=sa;password=;"
adoconn.connectionstring = sconn
adoconn.cursorlocation = aduseclient
adoconn.open
dim adocmd
set adocmd = server.createobject("adodb.command")
set adocmd.activeconnection = adoconn
dim squery
‘定義 for xml的查詢。具體的語法在以后的章節中將詳細介紹。
squery = "<root xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>select * from products order by productname for xml auto</sql:query></root>"
‘建立adodb stream 對象,adodb stream 對象需要ado2.5以上版本支持,它可以將記錄集轉換為數據流。
dim adostreamquery
set adostreamquery = server.createobject("adodb.stream")
adostreamquery.open
adostreamquery.writetext squery, adwritechar
adostreamquery.position = 0
adocmd.commandstream = adostreamquery
adocmd.dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
response.write "pushing xml to client for processing " & "<br/>"
adocmd.properties("output stream") = response
‘輸出xml格式的文本
response.write "<xml id=mydataisle>"
adocmd.execute , , adexecutestream
response.write "</xml>"
‘通過ie的xml解析器,使用dom方法將xml的文本轉換為html
 
兵器之二:xpath 
  w3c 于 1999 年 10 月 8 日提出的 xpath 語言規范,它是一種基于xml的查詢語言,它能在xml文擋中處理數據。sql server 2000 中實現的是該規范的子集。它把table和views作為xml的組件,并把columns作為xml屬性。sql server 2000的xml支持iis使用url或者模板的方式提交到sql server處理xpath查詢,并返回xml的結果。 
  支持的功能 
  下表顯示 sql server 2000 中實現的 xpath 語言的功能。
功能項目軸attribute、child、parent 和 self 軸包括連續謂詞和嵌套謂詞在內的布爾值謂詞 所有關系運算符=, !=, <, <=, >, >=算術運算符+, -, *, div顯式轉換函數number()、string()、boolean()布爾運算符and, or布爾函數true()、false()、not()xpath 變量 
  不支持的功能 
  下表顯示 sql server 2000 中沒有實現的 xpath 語言的功能。
功能項目軸ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling數值謂詞 算術運算符mod節點函數ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling字符串函數string()、concat()、starts-with()、contains()、substring-before()、substring-after()、substring()、string-length()、normalize()、translate()布爾函數lang()數字函數sum()、floor()、ceiling()、round()union 運算符|
  xpath 查詢是以表達式的形式指定的。位置路徑是一種比較常用表達式,用以選擇相對于上下文節點的節點集。位置路徑表達式的求值結果是節點集。 
xml 文檔
<root>
  <order productid="prod-28" unitprice="45.6" quantity="15">
  <discount>0.25</discount>
  </order> 
  <order productid="prod-39" unitprice="18" quantity="21">
  <discount>0.25</discount> 
  </order>
  <order productid="prod-46" unitprice="12" quantity="2"> 
  <discount>0.25</discount>
  </order> 
</root> 
  下面是查詢該xml 文檔的xpath位置路徑表達式,它的含義是返回根節點下所有<root>子元素下的productid屬性的屬性值為 "prod-39"的 <order> 元素。
  位置路徑的類型 
  可以分為絕對位置路徑和相對位置路徑。 
  絕對位置路徑以文檔的根節點開始,由斜杠 (/) 組成,后面可以是相對位置路徑。斜杠 (/) 選定文檔的根節點。 
  相對位置路徑以文檔的上下文節點(context)開始,由斜杠 (/) 所分開的一個或多個位置步驟序列組成。每個步驟都選定相對于上下文節點的節點集。初始步驟序列選定相對于上下文節點的節點集。節點集中的每個節點都用作后續步驟的上下文節點。由后續步驟標識的節點集聯接在一起。例如,child::order/child::orderdetail 選定上下文節點的<order> 子元素的 <orderdetail> 子元素。 
  位置步驟 (絕對或相對)位置路徑由包含下面三部分的位置步驟組成: 
  軸 
  軸指定位置步驟選定的節點與上下文節點之間的樹關系。sql server 2000 支持 parent、child、attribute 及 self 軸。 
  如果在位置路徑中指定 child 軸,查詢選定的所有節點都將是上下文節點的子節點。
比如說要查詢從當前的上下文節點中選定所有 <order>節點的子節點,可以使用 child:: order 
  如果指定 parent 軸,選定的節點將是上下文節點的父節點。 
比如說要查詢從當前的上下文節點中選定所有 <order>節點的父節點,可以使用 parent:: order 
  如果指定 attribute 軸,選定的節點是上下文節點的屬性。
比如說要查詢從當前的上下文節點中選定所有 <order>節點的屬性,可以使用 attribute:: order 
  節點測試 
  節點測試指定位置步驟選定的節點類型。每個軸(child、parent、attribute 和 self)都具有主要節點類型。對于 attribute 軸,主要節點類型是 <attribute>。對于 parent、child 和 self 軸,主要節點類型是 <element>。
  例如,如果位置路徑指定 child::order,則將選定上下文節點的 <order> 子元素。因為 child 軸以 <element> 為其主要節點類型,而且如果order是 <element> 節點,則節點測試order為 true。
  選擇謂詞(零個或多個)
  謂詞圍繞著軸篩選節點集。在 xpath 表達式中指定選擇謂詞與在 select 語句中指定 where 子句相似。謂詞在括號中指定。應用在選擇謂詞中指定的測試將對節點測試返回的節點進行篩選。對于要篩選的節點集中的每個節點,在對謂詞表達式取值時將此節點作為上下文節點,將節點集中的節點數作為上下文大小。如果謂詞表達式對此節點取值為 true,則此節點將包括在最后所得到的節點集中。
  例如: 
  1. child::order [attribute::productid="prod-39"] 表示從當前的上下文節點中選定productid屬性值為prod-39的所有 <order>子節點。
  2. child::order [child:: discount] 表示從當前的上下文節點中選定包含一個或多個 <discount> 子節點的所有 <order> 子節點。
  3. child::order [not(child:: discount)] 表示從當前的上下文節點中選定不包含 <discount> 子節點的所有 <order> 子節點。
  位置步驟的語法
  是用兩個冒號 (::) 分開的軸名和節點測試,后面是分別放在方括號中的零個或多個表達式。
  例如,在 xpath 表達式(位置路徑)child::order[attribute::productid="prod-39"]中,選定上下文節點的所有 <order> 子元素。然后將謂詞中的測試應用于節點集,將只返回 productid屬性的屬性值為 "prod-39"的 <order> 元素節點。 
  縮略語法 
  sqlservr2000支持下面的位置路徑縮略語法: 
  attribute::可以縮略為 @。 
  比如:[attribute::productid="prod-39"] 可以縮寫成 [@productid =" prod-39"] 
  child::可以在位置步驟中省略。
  比如:位置路徑child::root/child::orde可以縮寫成 root /order 
  self::node() 可縮略為一個句點 (.),而 parent::node() 可縮略兩個句點 (..)。
  所以 /child::root/child::order[attribute::productid="prod-39"]也可以縮寫成 /root/order[@productid="prod-39"]