在XPath中抽象存储数据结构

时间:2020-03-06 14:53:25  来源:igfitidea点击:

我有一个存储在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进行查询。