Meng Xianhui
XML (Extensible Markup Language: eXtensible Markup Language) はプラットフォームに完全に依存しないため、徐々にデータ送信の主要なメディアになりつつあります。 XML は自己記述言語であり、データ自体にはメタデータ、つまりデータ自体に関する情報がすでに含まれています。例: 「Mencius Chapter E 1757281793923net_lover1807581793923」 この一連のデータは、文字通りの意味を理解するのが難しく、いくつのデータ セグメントで構成されているかも明確ではありません。しかし、XML を使用してこれを記述すると、次のようになります。各データセグメントの意味を明確に確認できます。
<人物データ>
<人物>
<Name>孟子 第 E 章</Name>
<高さ>175</高さ>
<重量>72</重量>
<電話番号>81793923</電話番号>
</人>
<人物>
<name>ネット愛好家</name>
<高さ>180</高さ>
<体重>75</体重>
<電話番号>81793923</電話番号>
</人>
</人物データ>
上記の XML 部分から、各データが何を表しているのかが明確にわかるだけでなく、データがどこに分割されているかもわかります。通常のアプリケーションでは、得られる結果は配列、コレクション、またはレコードセットの形式になることがありますが、それらを自己記述型の XML 形式のデータに変換するにはどうすればよいでしょうか。データ形式の観点から見ると、XML は純粋な文字列の単純なテキスト形式であり、非常にシンプルで高速であり、配列は参照による転送が非常に遅く、コレクションや記録の処理が非常に面倒です。セットは両方ともオブジェクトであるため、処理中にコンピューターのパフォーマンスが低下します。また、これらのオブジェクトは特定のプラットフォームに関連付けられているため、プラットフォームにはオブジェクトの操作を処理する組み込みの処理メカニズムが必要です。 XML はすでに W3C 標準であり、プラットフォームに依存しません。私たちのコンピュータに必要なのは、単純な XML 文字列を処理できること、つまり、XML 文字列を解析し、インターフェイスを通じてデータを簡単に分解できることです。独立したデータセグメントにアクセスできるようにします。 XML パーサーは小型で高性能であり、あらゆるプラットフォームで見つけることができます。 XML データを受信し、それを上記の例のスタイルに解析したら、XSLT (eXstensible Stylesheet Language Transformations) を通じてさまざまな表現に変換できます。データ送信に XML データ形式を使用すると、アプリケーション コードの作成作業がよりシンプルかつ簡単になり、優れたスケーラビリティが得られます。
次に、データを変換する方法を見てみましょう。この例は、Microsoft Windows 2000、IIS5、MSXML3、および ADO2.6 で作成されています。サンプル データは、Microsoft SQL Server7.0 に付属の Northwind サンプル データベースを使用しています。 XML をサポートする SQL Server2000 ではなく SQL Server7 を使用する理由は、SQL Server2000 のような XML データ ソースをサポートするだけではなく、さまざまな種類のデータ ソースから取得したレコード セットを処理することを目的としています。 。 ADO にはさまざまな形式があり、さまざまな種類のデータ ソースを処理できるため、XML を使用すると、送信と解析が迅速に行えます。ただし、この例の処理方法は、Microsoft XML パーサー、ADO2.5 以降のバージョンの Windows、IIS、SQL Server を備えたあらゆる環境にも適しています。
わかりやすくするために、単価が 20 米ドル以下、在庫が 20 米ドル以上、製品名が 6 文字以下の製品のみを選択します。
<%
Dim objRecordset
Set objRecordset = Server.CreateObject("ADODB.Recordset")
objRecordset.open _
"商品名、単価、在庫単位を選択" _
& "製品から" _
& "WHERE 単価 <= 20 " _
& "AND 在庫数 >= 20 " _
& "AND LEN(製品名) <= 6 " _
& "商品名で注文", _
"プロバイダ=SQLOLEDB;" _
& "データ ソース=SomeSQLServer;" _
& "初期カタログ=ノースウィンド;"
& "ユーザー ID=MyUserName;" _
& "パスワード=私のパスワード;"
%>
ここでは、取得したレコードセットを 3 つの方法を使用して XML 形式に変換します。
まず、レコード セット全体を走査し、XML DOM (ドキュメント オブジェクト モデル) を使用して、XML ノード ツリーを構築します。
<%
Dim objXMLDOM、objRootNode、objNode
Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument")
objRootNode = objXMLDOM.createElement("xml") を設定します
objXMLDOM.documentElement = objRootNode
objRecordset.EOF ではないときに実行します
objRowNode = objXMLDOM.createElement("行") を設定します。
objNode = objXMLDOM.createElement("製品名") を設定します。
objNode.text = objRecordset.Fields.Item("製品名").Value
objRowNode.appendChild(objNode)
objNode = objXMLDOM.createElement("単価") を設定します。
objNode.text = objRecordset.Fields.Item("単価").Value
objRowNode.appendChild(objNode)
set objNode = objXMLDOM.createElement("UnitsInStock")
objNode.text = objRecordset.Fields.Item("UnitsInStock").Value
objRowNode.appendChild(objNode)
objRootNode.appendChild(objRowNode)
objRecordset.MoveNext
ループ
objNode = なしを設定します
objRowNode = なしを設定します
objRootNode = なしを設定します
objRecordset = なしを設定します
%>
これで、XML DOM オブジェクトが完成しました。 ADO レコードセット オブジェクトと XML DOM オブジェクトをシステム メモリに同時に格納する必要があるため、レコードセットが大きい場合、このメソッドのパフォーマンスは理想的ではありません。
2 番目の方法は、レコード セットを走査し、XML 文字列自体を直接生成することです。
<%
ディムstrXML
strXML = "<xml>"
objRecordset.MoveFirst
objRecordset.EOF ではないときに実行します
strXML = strXML & "<行>"
strXML = strXML & "<製品名>" _
& objRecordset.Fields.Item("製品名").Value _
& "</製品名>"
strXML = strXML & "<単価>" _
& objRecordset.Fields.Item("単価").Value _
& "</単価>"
strXML = strXML & "<在庫単位>" _
& objRecordset.Fields.Item("UnitsInStock").Value _
& "</単位在庫>"
strXML = strXML & "</row>"
objRecordset.MoveNext
ループ
strXML = strXML & "</xml>"
objRecordset = なしを設定します
%>
ただし、上記の 2 つの方法の最大の欠点は、コードを再利用できないことです。別のフィールドにクエリを実行する場合は、別のノードのニーズに合わせてコードも手動で変更する必要があります。以下のアプローチはより一般的になります。
3 番目の方法: 再利用可能な方法。
<%
ディムstrXML
strXML = "<xml>"
objRecordset.MoveFirst
objRecordset.EOF ではないときに実行します
strXML = strXML & "<行>"
objRecordset.Fields の各 varItem について
strXML = strXML _
& "<" & varItem.name & ">" _
&varItem.value_
& "</" & varItem.name & ">"
次
strXML = strXML & "</row>"
objRecordset.MoveNext
ループ
strXML = strXML & "</xml>"
objRecordset = なしを設定します
%>
より効果的な方法は、レコードセットの組み込みの save メソッドを直接使用することです。これにより、save メソッドを呼び出した後、すぐにメモリ内のレコードセット オブジェクト インスタンスを解放できます。これにより、レコードセットの内容が XML 形式に自動的に変換されます。 。 save メソッドには 2 つのパラメータがあります。1 つは XML が保存される場所であり、もう 1 つはデータが保存される形式を示すインジケータです。データは XML DOM オブジェクト (ADO STREAM オブジェクト) として保存することも、ASP RESPONSE オブジェクトとして直接保存することもできます。汎用性を高めるために、データを XML DOM として保存し、2 番目のパラメーターに adPersistXML ADO 定数を使用します。 。その方法は次のとおりです。
<%
定数 adPersistXML = 1
Dim objXMLDOM
Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
objRecordset.save objXMLDOM、adPersistXML
objRecordset = なしを設定します
%>
この方法は便利で、高速で、エラーがありません。さまざまなクエリに対してノード名を手動で変更する必要はありません。ただし、このメソッドで生成される 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
名前 = "行"
content="eltのみ"
rs:CommandTimeout="30">
<s:AttributeType
name="製品名"
rs:number="1"
rs:writeunknown="true">
<s:datatype
dt:type="文字列"
dt:maxLength="40"
rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType
名前="単価"
rs:number="2"
rs:nullable="true"
rs:writeunknown="true">
<s:datatype
dt:type="数値"
rs:dbtype="通貨"
dt:maxLength="8"
rs:precision="19"
rs:fixedlength="true"/>
</s:AttributeType>
<s:AttributeType
名前 = 在庫単位"
rs:number="3"
rs:nullable="true"
rs:writeunknown="true">
<s:datatype
dt:type="i2"
dt:maxLength="2"
rs:precision="5"
rs:fixedlength="true"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row
商品名=「チャイ」
単価 = "18"
UnitsInStock="39"/>
<z:row
商品名=「昆布」
単価="6"
UnitsInStock="24"/>
<z:row
商品名=豆腐
単価 = "23.25"
UnitsInStock="35"/>
</rs:data>
</xml>
ADO によって自動的に生成された XML には、この XML で許可されるノードと属性、使用されるデータ型、およびデータ ノードが記述されるスキーマ情報が含まれています。名前空間も増加しました。スキーマ情報は、データ検証が必要な場合やより複雑な処理に役立つ場合がありますが、ほとんどの場合、シン クライアントを使用しているため、スキーマ情報は必要ありません。 XSLT を使用すると、必要な情報を分離し、冗長な情報を削除できます。したがって、次の「DataCleaner.xsl」を記述します。
<?xml バージョン="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
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">
<xsl:output submit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:要素名="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:要素名="行">
<xsl:for-each select="@*">
<xsl:要素名="{名前()}">
<xsl:value-of select="."/>
</xsl:要素>
</xsl:for-each>
</xsl:要素>
</xsl:for-each>
</xsl:要素>
</xsl:テンプレート>
</xsl:スタイルシート>
この XSLT には再利用可能な機能があり、さまざまなクエリ結果に適用できます。この XSLT の使用方法の例を次に示します。
<%
Dim strCleanXML、objXMLDOM_XSLT
set objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument")
objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl"))
strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)
objXMLDOM = なしを設定します
objXMLDOM_XSLT = なしを設定します
%>
上記の処理の後、strClaenXML が必要な XML 文字列になります。
<xml>
<行>
<ProductName>チャイ</ProductName>
<単価>18</単価>
<在庫数>39</在庫数>
</行>
<行>
<ProductName>昆布</ProductName>
<単価>6</単価>
<在庫数>24</在庫数>
</行>
</xml>
上記の形式の XML 文字列は、フィールドをノードに処理するのではなく、属性ノードに処理する場合によく見られるノード セットのスタイルです。DataCleaber にわずかな変更を加えるだけで済みます。 xsl:
<?xml バージョン="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
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">
<xsl:output submit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:要素名="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:要素名="行">
<xsl:for-each select="@*">
<xsl:属性名="{名前()}">
<xsl:value-of select="."/>
</xsl:属性>
</xsl:for-each>
</xsl:要素>
</xsl:for-each>
</xsl:要素>
</xsl:テンプレート>
</xsl:スタイルシート>
以下は、新しいスタイルを使用した結果です。このスタイルは、フィールドの長さを表すためにノードを使用するよりもはるかに短くなります。転送速度が速くなります:
<xml>
<row ProductName="チャイ" UnitPrice="18" UnitsInStock="39"/>
<row ProductName="昆布" UnitPrice="6" 在庫数="24"/>
</xml>
これまで、ADO レコード セットから XML 形式のデータを取得するいくつかの方法を紹介し、最も単純化された文字列も取得しました。ただし、一部のフィールド値には、P&G Procter & Gamble の名前など、XML でサポートされていない文字が含まれています。 Chef Anton の Gumbo Mix 製品など。変換時にこれを行う必要があります。 エンコード処理を実行します。 Microsoft ADO 2.6 SDK の save メソッドを使用する場合、次の点に注意する必要があります。 1. save メソッドは、開いている Recordset でのみ機能します。 adVariant、adIDispatch、および adIUnknown タイプのフィールドはサポートされていません。 3. 階層レコードセット (データ形状) を保存する場合、パラメータ化と未解決の更新を含むレコードセットは保存できません。
パフォーマンスをさらに向上させるために、変換作業を COM/COM+ コンポーネントに組み込むことができ、ASP コードはデータの最終的な表示のみを実行します。ビジネス層、データ層、プレゼンテーション層を分離する必要があるのは、データ コンポーネントを呼び出すことだけです。データ コンポーネントはデータベースのストアド プロシージャを呼び出し、結果を XML に変換し、最後に単純な XML 文字列を ASP プログラムに返すだけです。 、ASP は XSLT を使用して XML を変換し、結果をブラウザーに送信できます。