在XPath中抽象存储数据结构
我有一个存储在XDocuments和DataTables中的数据集合,我想用XPath查询作为一个统一的数据空间来解决这两个问题。因此,例如," / Root / Tables / Orders / FirstName"将在名为" Orders"的数据表的每一行中提取Firstname列的值。
有没有一种方法可以将DataTable中的所有记录都复制到XDocument中呢?
我正在使用.Net 3.5
解决方案
我们是否在寻找与我询问的有关XPath外键的类似内容?
正如XPath建议所说:" XPath的主要目的是解决XML文档的某些部分。"它没有用于处理一个以上XML文档的部分的任何功能。如果我们想做我们想做的事情,则必须构建一个XML文档。
我们将必须合并文档,或者至少对所有文档执行相同的转换。我们可能会考虑将文档移动到单个DataTable,如果XPath / XSLT不可行,则对DataTable进行过滤。
.NETs XPath东西在IXPathNavigable接口上运行。每个IXPathNavigable都有一个CreateNavigator()方法,该方法返回一个IXPathNavigator。
为了将所有数据源公开为一个大文档,我们需要创建一个实现IXPathNavigable的类,其中包含所有xpath数据源。 CreateNavigator方法应该返回一个自定义XPathNavigator,该XPathNavigator将内容公开为一个大型数据源。
不幸的是,实施此导航器有些麻烦,尤其是在文档之间跳转时,必须格外小心,
我最终自己找出了答案。我在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])))))
结果是一个XElement(TableRoot),其结构类似于以下内容,假定字典包含一个名为" Orders"的表,其中有两行。
<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进行查询。