【 ADO + XML + DHTML 】

1. レコードセットを XML 形式で保存
2. XML データの復帰
3. データの追加・ソート・条件
4. XML Data Island
5. XML ドキュメントオブジェクト
6. XSL を使用して表示
7. レコードセットから作成した XML を XSL で表示
8. XML ドキュメントオブジェクトより直接レコードセットを作成

  • このコードでは上書き保存はできません

  • savexml.htaで実行します savexml.htm で実行する場合は、save.xml を絶対パスで指定して下さい

  • <SCRIPT language=VBScript>
     
    Const adPersistXML = 1
     
    function CreateXML()
     
    	Set Rs = CreateObject( "ADODB.Recordset" )
     
    	GetConnectionString = _
    		"Provider=SQLOLEDB;" & _
    		"Data Source=localhost;" & _
    		"Initial Catalog=lightbox;" &  _
    		"User ID=sa;" & _
    		"Password=;"
     
    	Rs.Open "select * from 商品マスタ", GetConnectionString
    	Rs.Save "save.xml", adPersistXML
    	Rs.Close
     
    	Set Rs = Nothing
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call CreateXML()'>
    </BODY>
    </HTML>
    


  • 以下が保存された内容です

  • <xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
    	xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
    	xmlns:rs='urn:schemas-microsoft-com:rowset'
    	xmlns:z='#RowsetSchema'>
    <s:Schema id='RowsetSchema'>
    	<s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
    		<s:AttributeType name='c0' rs:name='コード' rs:number='1' rs:writeunknown='true'>
    			<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='4' rs:maybenull='false'/>
    		</s:AttributeType>
    		<s:AttributeType name='c1' rs:name='商品名' rs:number='2' rs:nullable='true' rs:writeunknown='true'>
    			<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='50'/>
    		</s:AttributeType>
    		<s:AttributeType name='c2' rs:name='単価' rs:number='3' rs:nullable='true' rs:writeunknown='true'>
    			<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/>
    		</s:AttributeType>
    		<s:extends type='rs:rowbase'/>
    	</s:ElementType>
    </s:Schema>
    <rs:data>
    	<z:row c0='0001' c1='パソコン' c2='100600'/>
    	<z:row c0='0002' c1='テレビ' c2='50600'/>
    </rs:data>
    </xml>
    

  • loadxml.htm

  • <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	Dim OutText
     
    	Set Rs = CreateObject( "ADODB.Recordset" )
    	Set Sm = CreateObject( "ADODB.Stream" )
     
    	Sm.Open
    	Sm.WriteText document.all("xml").innerHTML
    	Sm.Position = 0
     
    	Rs.Open Sm
    	Sm.Close
     
    	OutText = "<TABLE border=1 cellpadding=5>"
    	For i = 0 to Rs.Fields.Count - 1
    		OutText = OutText & "<TH>" & Rs.Fields(i).name & "</TH>"
    	Next
    	Do while not Rs.EOF
    		OutText = OutText & "<TR>"
    		For i = 0 to Rs.Fields.Count - 1
    			OutText = OutText & "<TD>" & Rs.Fields(i).value & "</TD>"
    		Next
    		OutText = OutText & "</TR>"
    		Rs.MoveNext
    	Loop
    	OutText = OutText & "</TABLE>"
    	document.all("DispArea").innerHTML = OutText
     
    	Rs.Close
     
    	Set Sm = Nothing
    	Set Rs = Nothing
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
    <DIV id=DispArea>
    </DIV>
    <DIV id=xml><xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
    	...省略...
    </xml></DIV>
    </BODY>
    </HTML>
    


  • 以下が実行結果です
  • コード商品名単価
    0001パソコン100600
    0002テレビ50600


    <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	Dim OutText
     
    	Set Rs = CreateObject( "ADODB.Recordset" )
    	Set Sm = CreateObject( "ADODB.Stream" )
     
    	Sm.Open
    	Sm.WriteText document.all("xml").innerHTML
    	Sm.Position = 0
     
    	Rs.LockType = 3	' 更新可能にする
    	Rs.Open Sm
    	Sm.Close
     
    	Rs.AddNew		' 追加用バッファの確保
     
    	Rs.Fields(0).value = "0003"
    	Rs.Fields(1).value = "冷蔵庫"
    	Rs.Fields(2).value = "70000"
     
    	Rs.Update		' 更新
     
    	Rs.MoveFirst		' 先頭へ移動
     
    	Rs.Sort = "単価"		' order by 句の構文
    	Rs.Filter = "単価 < 80000"	' where 句の構文
     
    	OutText = "<TABLE border=1 cellpadding=5>"
    	For i = 0 to Rs.Fields.Count - 1
    		OutText = OutText & "<TH>" & Rs.Fields(i).name & "</TH>"
    	Next
    	Do while not Rs.EOF
    		OutText = OutText & "<TR>"
    		For i = 0 to Rs.Fields.Count - 1
    			OutText = OutText & "<TD>" & Rs.Fields(i).value & "</TD>"
    		Next
    		OutText = OutText & "</TR>"
    		Rs.MoveNext
    	Loop
    	OutText = OutText & "</TABLE>"
    	document.all("DispArea").innerHTML = OutText
     
    	Rs.Close
     
    	Set Sm = Nothing
    	Set Rs = Nothing
     
    end function
    </SCRIPT>
    

    <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	Dim OutText
     
    	Set Rs = CreateObject( "ADODB.Recordset" )
    	Set Sm = CreateObject( "ADODB.Stream" )
     
    	Sm.Open
    	Sm.WriteText document.all("xml").innerHTML
    	Sm.Position = 0
     
    	Rs.LockType = 3
    	Rs.Open Sm
    	Sm.Close
     
    	Rs.AddNew
     
    	Rs.Fields(0).value = "0003"
    	Rs.Fields(1).value = "冷蔵庫"
    	Rs.Fields(2).value = "70000"
     
    	Rs.Update
     
    	Rs.MoveFirst
     
    	Rs.Sort = "単価"
     
     
    	OutText = "<XML id=""xmlDataisland"">" & vbCrLf
    	OutText = OutText & "<goods>" & vbCrLf
    	Do while not Rs.EOF
    		OutText = OutText & "<goodsrow>" & vbCrLf
    		For i = 0 to Rs.Fields.Count - 1
    			OutText = OutText & "<" & Rs.Fields(i).name & ">"
    			OutText = OutText & Rs.Fields(i).value 
    			OutText = OutText & "</" & Rs.Fields(i).name & ">" & vbCrLf
    		Next
    		OutText = OutText & "</goodsrow>" & vbCrLf
    		Rs.MoveNext
    	Loop
    	OutText = OutText & "</goods>" & vbCrLf
    	OutText = OutText & "</XML>" & vbCrLf
     
    	OutText = OutText & "<SPAN datasrc=""#xmlDataisland"" style='display:none'>" & vbCrLf
     
    	document.all("DispArea").innerHTML = OutText
     
    	Rs.Close
     
    	Set Sm = Nothing
    	Set Rs = Nothing
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
     
     ここから XMLデータアイランドを動的に作成するエリア 
    <DIV id=DispArea>
    </DIV>
     ここまで XMLデータアイランドを動的に作成するエリア 
     
     
     ここから XMLデータをバインドする HTML 
    <TABLE border=1 cellpadding=5 datasrc="#xmlDataisland">
    <THEAD><TH>コード</TH><TH>商品名</TH><TH>単価</TH></THEAD>
    <TR>
    	<TD><SPAN datafld="コード"></SPAN></TD>
    	<TD><SPAN datafld="商品名"></SPAN></TD>
    	<TD><SPAN datafld="単価"></SPAN></TD>
    </TR>
    </TABLE>
     ここまで XMLデータをバインドする HTML 
     
     
     ここから ADO レコードセット 互換 XML 
    <DIV id=xml><xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
    	...省略...
    </xml></DIV>
     ここまで ADO レコードセット 互換 XML 
     
     
    </BODY>
    </HTML>
    


  • 動的に作成した部分は以下のようになります
    ( インデントは便宜上後から付けたものです )
  • <XML id="xmlDataisland">
    	<goods>
    		<goodsrow>
    			<コード>0002</コード>
    			<商品名>テレビ</商品名>
    			<単価>50600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0003</コード>
    			<商品名>冷蔵庫</商品名>
    			<単価>70000</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0001</コード>
    			<商品名>パソコン</商品名>
    			<単価>100600</単価>
    		</goodsrow>
    	</goods>
    </XML>
    <SPAN datasrc="#xmlDataisland" style='display:none'>
    
  • 一番最後の部分がポイントです。動的にデータアイランドを既に HTML 上にあるテーブルにバインドする
    には、ダミーとして同時に解析される バインドを定義したタグが必要になります

  • <XML id="...">〜</XML><XML id="..." SRC="........."></XML> という書き方もできます
    つまり、バインドするデータをサーバ側で作るという方法もあります
    (その場合最後の1行は必要ありません)
  • <XML id="...">〜</XML> は、DHTML として一つのオブジェクトとなり、アクセスするする事のできる
    コレクション・メソッド・プロパティがあります
  • <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	With document.all("xmlDataisland").XMLDocument.documentElement.childNodes
     
    		document.all("MyTable").rows(0).cells(0).innerText = "コード"
    		document.all("MyTable").rows(0).cells(1).innerText = "商品名"
    		document.all("MyTable").rows(0).cells(2).innerText = "単価"
    		For i = 0 to 2
    			document.all("MyTable").rows(i+1).cells(0).innerText = _
    				.item(i).childNodes(0).text
    			document.all("MyTable").rows(i+1).cells(1).innerText = _
    				.item(i).childNodes(1).text
    			document.all("MyTable").rows(i+1).cells(2).innerText = _
    				.item(i).childNodes(2).text
    		Next
     
    	End With
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
     
    <TABLE id=MyTable border=1 cellpadding=5>
    <THEAD><TH></TH><TH></TH><TH></TH></THEAD>
    <TR><TD></TD><TD></TD><TD></TD></TR>
    <TR><TD></TD><TD></TD><TD></TD></TR>
    <TR><TD></TD><TD></TD><TD></TD></TR>
    </TABLE>
     
    <XML id="xmlDataisland">
    	<goods>
    		<goodsrow>
    			<コード>0001</コード>
    			<商品名>パソコン</商品名>
    			<単価>100600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0002</コード>
    			<商品名>テレビ</商品名>
    			<単価>50600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0003</コード>
    			<商品名>冷蔵庫</商品名>
    			<単価>70000</単価>
    		</goodsrow>
    	</goods>
    </XML>
     
    </BODY>
    </HTML>
    


  • XMLDocument はXML オブジェクトモデル(DOM) への参照です

  • documentElement はXML 文書のルートです

  • childNodes 子ノードのコレクションです

  • item( n ) は、コレクションのメソッドで、インデックスを指定してオブジェクトを参照します
    通常このメソッドは省略して、コレクション( n ) とする事ができます

  • コレクションには、通常 length というコレクションの数を示すプロパティがあります
  • <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	document.all("DispArea").innerHTML = _
    		document.all("xmlDataisland").transformNode( _
    			document.all("xslDataisland").documentElement _
    		)
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
     
    <DIV id=DispArea>
    </DIV>
     
    <XML id="xmlDataisland">
    	<goods>
    		<goodsrow>
    			<コード>0001</コード>
    			<商品名>パソコン</商品名>
    			<単価>100600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0002</コード>
    			<商品名>テレビ</商品名>
    			<単価>50600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0003</コード>
    			<商品名>冷蔵庫</商品名>
    			<単価>70000</単価>
    		</goodsrow>
    	</goods>
    </XML>
     
    <XML id="xslDataisland">
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
     
    <xsl:template match="/">
     
    	<TABLE border="1">
    	<THEAD><TH>コード</TH><TH>商品名</TH><TH>単価</TH></THEAD>
    	<xsl:for-each select="goods/goodsrow">
    		<TR>
    		<TD><xsl:value-of select="コード" /></TD>
    		<TD><xsl:value-of select="商品名" /></TD>
    		<TD><xsl:value-of select="単価" /></TD>
    		</TR>
    	</xsl:for-each>
    	</TABLE>
     
    </xsl:template>
     
    </xsl:stylesheet>
    </XML>
     
    </BODY>
    </HTML>
    


  • この例では、HTML に埋め込んでしまっていますが以下のように別ファイルにするのが本来の使い方です

  • 特に、XSL は文法上のエラーに厳密で、問題があると実行できません。属性の "" も省略できません

  • IE でエラーの場所をチェックできるので、別ファイルにするほうが良いでしょう


  • <XML id="xmlDataisland" src="xmlDataisland.xml"></XML>
    <XML id="xslDataisland" src="xmlDataisland.xsl"></XML>
    

  • ado.htm
  • <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	document.all("DispArea").innerHTML = _
    		document.all("xmlDataisland").transformNode( _
    			document.all("xslDataisland").documentElement _
    		)
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
     
    <DIV id=DispArea>
    </DIV>
     
    <XML id="xmlDataisland" src="ado.xml"></XML>
    <XML id="xslDataisland" src="ado.xsl"></XML>
     
    </BODY>
    </HTML>
    


  • ado.xml
  • <xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
    	xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
    	xmlns:rs='urn:schemas-microsoft-com:rowset'
    	xmlns:z='#RowsetSchema'>
    <s:Schema id='RowsetSchema'>
    	<s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
    		<s:AttributeType name='c0' rs:name='コード' rs:number='1' rs:writeunknown='true'>
    			<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='4' rs:maybenull='false'/>
    		</s:AttributeType>
    		<s:AttributeType name='c1' rs:name='商品名' rs:number='2' rs:nullable='true' rs:writeunknown='true'>
    			<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='50'/>
    		</s:AttributeType>
    		<s:AttributeType name='c2' rs:name='単価' rs:number='3' rs:nullable='true' rs:writeunknown='true'>
    			<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/>
    		</s:AttributeType>
    		<s:extends type='rs:rowbase'/>
    	</s:ElementType>
    </s:Schema>
    <rs:data>
    	<z:row c0='0001' c1='パソコン' c2='100600'/>
    	<z:row c0='0002' c1='テレビ' c2='50600'/>
    </rs:data>
    </xml>
    


  • ado.xsl
  • <?xml version="1.0" encoding="Shift_JIS"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
     
    <xsl:template match="/">
     
    	<TABLE border="1">
     
    	<THEAD>
    	<xsl:for-each select="//s:AttributeType">
    		<TH><xsl:value-of select="@rs:name" /></TH>
    	</xsl:for-each>
    	</THEAD>
     
    	<xsl:for-each select="//z:row">
    		<TR>
    		<TD><xsl:value-of select="@c0" /></TD>
    		<TD><xsl:value-of select="@c1" /></TD>
    		<TD><xsl:value-of select="@c2" /></TD>
    		</TR>
    	</xsl:for-each>
    	</TABLE>
     
    </xsl:template>
     
    </xsl:stylesheet>
    

    <SCRIPT language=VBScript>
     
    function LoadXML()
     
    	Dim OutText
     
    	Set Rs = document.all("xmlDataisland").namedRecordset("")
     
    	Rs.AddNew
     
    	Rs.Fields(0).value = "0003"
    	Rs.Fields(1).value = "冷蔵庫"
    	Rs.Fields(2).value = "70000"
     
    	Rs.Update
     
    	Rs.MoveFirst
     
    	OutText = "<TABLE border=1 cellpadding=5>" & vbCrLf
    	For i = 0 to Rs.Fields.Count - 1
    		OutText = OutText & "<TH>" & Rs.Fields(i).name & "</TH>"
    	Next
    	Do while not Rs.EOF
    		OutText = OutText & "<TR>" & vbCrLf
    		For i = 0 to Rs.Fields.Count - 1
    			OutText = OutText & "<TD>" & Rs.Fields(i).value & "</TD>"
    		Next
    		OutText = OutText & "</TR>" & vbCrLf
    		Rs.MoveNext
    	Loop
    	OutText = OutText & "</TABLE>" & vbCrLf
     
    	document.all("DispArea").innerHTML = OutText
     
    	Rs.Close
     
    	Set Rs = Nothing
     
    	document.all("work").value = OutText
     
     
    end function
    </SCRIPT>
    <HTML>
    <HEAD>
    <TITLE>XML</TITLE>
    </HEAD>
    <BODY>
    <INPUT type=button value="実行" onClick='Call LoadXML()'>
     
    <DIV id=DispArea>
    </DIV>
     
    <XML id="xmlDataisland">
    	<goods>
    		<goodsrow>
    			<コード>0001</コード>
    			<商品名>パソコン</商品名>
    			<単価>100600</単価>
    		</goodsrow>
    		<goodsrow>
    			<コード>0002</コード>
    			<商品名>テレビ</商品名>
    			<単価>50600</単価>
    		</goodsrow>
    	</goods>
    </XML>
     
    </BODY>
    </HTML>
    


  • 以下が実行結果です
  • コード商品名単価$Text
    0001パソコン1006000001 パソコン 100600
    0002テレビ506000002 テレビ 50600
    0003冷蔵庫700000003冷蔵庫70000




  • (注意) ソートや条件は使用できません