Visual Studio クライアント アプリケーションでの xml データ型の使用

この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。

xml データ型を使用すると、1 つの最上位要素が不足している XML インスタンスなどの XML フラグメント、および有効な XML ドキュメントを SQL Server データベースに格納できます。このデザインの特性により、xml データ型のインスタンスは、System.Xml.XmlDocument として返されるのではなく、Visual Studio 2005 で System.Xml.XmlNode の配列にマップされる必要があります。この処理では、断片化された XML がサポートされません。

xml データ型のインスタンスの値に含まれる XmlNode の配列を直接操作すると、InnerXml メンバ プロパティと OuterXml メンバ プロパティの動作方法の違いに気付きます。これは特に、xml データ型のインスタンスにより、1 つの最上位要素を持つ XML ドキュメントなどの有効な XML ドキュメントが作成される場合に当てはまります。

たとえば、SQL Server エンドポイント (MyServer.sql_endpoint) の新しいインスタンスを、xml データ型の行のインスタンス値を返す Web メソッド (GetSomeXml) を持つ Web プロキシとして起動する次のコード行があるとします。

MyServer.sql_endpoint proxy = new MyServer.sql_endpoint();
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
SqlXmlDt = proxy.MyServerdboGetSomeXml();
System.Xml.XmlNode[] nodeArr = SqlXmlDt.Any;
string xmlJustChildren = nodeArr[0].InnerXml;
string xmlWithRoot = nodeArr[0].OuterXml;

返された xml データ型の行の値には次のデータが含まれています。

<root><child/><child/></root>

上記のコードに示したように、nodeArr[0] の InnerXml プロパティと OuterXml プロパティが文字列変数のペア (xmlJustChildren と xmlWithRoot) に割り当てられると、nodeArr[0].InnerXml の値には現在の要素 (<root> 要素自体ではなく、両方の <child/> 要素) 内に含まれているノードのみが含まれ、nodeArr[0].OuterXml は期待どおりに動作します。つまり、XmlNodes の配列内のすべてのノード (<child/> 要素、および <root> 要素) が含まれます。

この動作は、XmlDocument を使用した作業に慣れている場合は、通常目にする動作とは異なるという点に注意してください。これは、そのクラスでの InnerXml プロパティと OuterXml プロパティの実装が異なるためです。XmlDocument インスタンスの場合、ドキュメント インスタンスは、ドキュメント内のすべての XmlNodes に対するラッパー要素の役目を果たします。これには、最上位のルート ノードと、ドキュメントに含まれるすべてのインライン DTD またはインライン スキーマが含まれます。したがって、XmlDocument.InnerXml のコンテンツは XmlDocument.OuterXml と同じになります。

このような実装仕様であるため、System.Xml.XmlDocumentFragment を使用することは、ネイティブ XML Web サービスで機能するクライアント アプリケーションで SQL Serverxml データ型のインスタンスを使用して作業する場合の適切な代替手段になります。XmlDocumentFragment クラスは、XmlDocument を使用することに慣れている開発者にとってより馴染み深いものになります。また、XmlDocumentFragment は、問題なく XmlNode の配列を受け取ります。

この後の各セクションでは、コードを提供し、XmlDocumentFragment を使用してクライアント アプリケーションで SQL Serverxml データ型のインスタンスの値を操作する方法の概要について説明します。

XmlDocumentFragment を使用した出力の処理

次のコード行は、XmlNode の配列を XmlDocumentFragment に格納してから、XPath 式を使用してフラグメントからノードを選択する方法を示しています。

System.Xml.XmlDocumentFragment fragOut = SqlXmlDt.Any[0].OwnerDocument.CreateDocumentFragment();

//  Loop over your XmlNode array and populate your XmlDocumentFragment.
foreach (System.Xml.XmlNode xmlnode in SqlXmlDt.Any)
{
    fragOut.AppendChild(xmlnode);
}

//  Loop over your XPath expression/selection for results.
foreach (System.Xml.XmlNode xmlpath in fragOut.SelectNodes("//bar"))
{
    System.Console.WriteLine(xmlpath.OuterXml);
}

XmlDocumentFragment を使用した文字列による入力の作成

次のコード行は、XmlDocumentFragment の InnerXml プロパティに文字列を代入して、XmlNode の入力配列を作成する方法を示しています。

//  Create an owning XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();

//  Create your XmlDocumentFragment.
System.Xml.XmlDocumentFragment fragIn = xmldoc.CreateDocumentFragment();

//  Fill the XmlDocumentFragment with a string.
fragIn.InnerXml =
"  <a>" +
"    <b>inputvalue</b>" +
"  </a>" +
"  topstuff" +
"  <b/>";

//  Create an XmlNode array (should never require more than one element).
System.Xml.XmlNode[] xmlnodes = new System.Xml.XmlNode[1];

//  Put the XmlDocumentFragment in the array and fill your XmlDt
xmlnodes[0] = (System.Xml.XmlNode) fragIn;
SqlXmlDt.Any = xmlnodes;

XmlDocumentFragment を使用したファイルからの入力の作成

インスタンスにデータを格納する方法に関しては、XmlDocumentFragment クラスは XmlDocument クラスよりも制限されています。次の例は、System.Xml.XmlReader を使用してファイルから XmlDocumentFragment インスタンスにデータを格納する方法を示しています。

//  Create an owning XmlDocument.
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();

//  Create your XmlDocumentFragment.
System.Xml.XmlDocumentFragment fragIn = xmldoc.CreateDocumentFragment();

//  Build an XmlReader from the file.
System.Xml.XmlReaderSettings rs = new System.Xml.XmlReaderSettings();
rs.ConformanceLevel = System.Xml.ConformanceLevel.Fragment;
System.Xml.XmlReader reader = System.Xml.XmlReader.Create("c:\\file.xml", rs);

//  Populate the fragment with the nodes from the XmlReader.
System.Xml.XmlNode child;
while (null != (child = xmldoc.ReadNode(reader)))
     fragIn.AppendChild(child);

//  Create your XmlNode array (should never require more than one element)
    System.Xml.XmlNode[] xmlnodes = new System.Xml.XmlNode[1];

//  Put the XmlDocumentFragment in the array and fill our XmlDt.
xmlnodes[0] = (System.Xml.XmlNode) fragIn;
SqlXmlDt.Any = xmlnodes;