XPath内のストレージデータ構造の抽象化
質問
XDocumentsとDataTablesに保存されたデータのコレクションがあり、XPathクエリを使用して両方を単一の統合データスペースとして扱いたいと思います。したがって、たとえば、「quote / Root / Tables / Orders / FirstName」」 " Orders"という名前のDataTableのすべての行のFirstname列の値を取得します。
DataTableのすべてのレコードをXDocumentにコピーせずにこれを行う方法はありますか?
.Net 3.5を使用しています
解決 2
私は最終的に自分自身でこの答えを見つけました。 System.Xml.LINQでXStreamingElementというクラスを発見しました。このクラスは、LINQ式からオンザフライでXML構造を作成できます。 DataTableをXMLスペースにキャストする例を次に示します。
Dictionary<string,DataTable> Tables = new Dictionary<string,DataTable>();
// ... populate dictionary of tables ...
XElement TableRoot = new XStreamingElement("Tables",
from t in Tables
select new XStreamingElement(t.Key,
from DataRow r in t.Value.Rows
select new XStreamingElement("row",
from DataColumn c in t.Value.Columns
select new XElement(c.ColumnName, r[c])))))
結果は、辞書に&quot; Orders&quot;という1つのテーブルが含まれていると仮定して、次のような構造を持つXElement(TableRoot)です。 2行あります。
<Tables>
<Orders>
<row>
<sku>12345</sku>
<quantity>2</quantity>
<price>5.95</price>
</row>
<row>
<sku>54321</sku>
<quantity>3</quantity>
<price>2.95</price>
</row>
</Orders>
</Tables>
それは、より大きなXElement / XDocumentベースの階層とマージでき、XPathでクエリできます。
他のヒント
.NETs XPathスタッフはIXPathNavigableインターフェイスで動作します。すべてのIXPathNavigableには、IXPathNavigatorを返すCreateNavigator()メソッドがあります。
すべてのデータソースを1つの大きなドキュメントとして公開するには、すべてのxpathデータソースを含むIXPathNavigableを実装するクラスを作成する必要があります。 CreateNavigatorメソッドは、コンテンツを1つの大きなデータソースとして公開するカスタムXPathNavigatorを返す必要があります。
残念ながら、このナビゲーターの実装はやや面倒で、特にドキュメント間をジャンプするときは注意が必要です
XPathの推奨事項にあるように、「XPathの主な目的は、XMLドキュメントの一部に対処することです。」複数のXMLドキュメントの一部をアドレス指定する機能はありません。しようとしていることを実行する場合は、単一のXMLドキュメントを作成する必要があります。
ドキュメントを結合するか、少なくともすべてのドキュメントで同じ変換を実行する必要があります。ドキュメントを単一のDataTableに移動し、XPath / XSLTが実行できない場合はDataTableをフィルタリングすることを検討できます。