1

这是交易。我有一个包含很多记录的 XML 文档。像这样的东西:

print("<?xml version="1.0" encoding="utf-8" ?>
      <Orders>
       <Order>
         <Phone>1254</Phone>
         <City>City1</City>
      <State>State</State>
      </Order>
      <Order>
         <Phone>98764321</Phone>
         <City>City2</City>
        <State>State2</State>
      </Order>  
     </Orders>");

还有一个 XSD 模式文件。我想从此文件中提取数据并将这些记录插入到数据库表中。首先,我想验证每个订单记录。例如,如果文件中有 5 个订单,其中 2 个未通过验证,我想将通过验证的 3 个插入 db 并留下另外 2 个。一个 xml 文件中可能有数千条记录。这里最好的方法是什么。以及验证将如何进行,因为我需要丢弃失败的记录并仅使用通过验证的记录。目前我正在使用XmlReaderSettings来验证 XML 文档记录。在插入数据库之前,我是否应该将这些记录提取到另一个 XML 文件或数据集或自定义对象中。我正在使用.Net 3.5。欢迎任何代码或链接。

4

5 回答 5

1

如果数据相当干净地映射到对象模型,您可以尝试使用 xsd.exe 从 .xsd 生成一些类,并将这些类处理到您选择的 DAL 中。问题是,如果容量很大(您提到数千条记录),您很可能会有很多往返。

另一种选择可能是将数据“按原样”传递到数据库并使用 SQL/XML 处理 TSQL 中的数据 - 大概作为接受 xml 类型参数的存储过程(SQL Server 2005 等)。

于 2008-10-22T14:08:44.957 回答
1

我同意你应该使用 XmlReader 的想法,但我想我会尝试一些不同的东西。

基本上,我首先验证整个 XDocument,然后如果有错误,我会枚举订单并根据需要对它们进行分类。它不漂亮,但也许它会给你一些想法。

        XDocument doc = XDocument.Load("sample.xml");
        XmlSchemaSet schemas = new XmlSchemaSet();
        schemas.Add("", "sample.xsd");

        bool errors = false;
        doc.Validate(schemas, (sender, e) =>
        {
            errors = true;
        });

        List<XElement> good = new List<XElement>();
        List<XElement> bad = new List<XElement>();
        var orders = doc.Descendants("Order");
        if (errors)
        {
            foreach (var order in orders)
            {
                errors = false;
                order.Validate(order.GetSchemaInfo().SchemaElement, schemas, (sender, e) =>
                {
                    errors = true;
                });

                if (errors)
                    bad.Add(order);
                else
                    good.Add(order);
            }
        }
        else
        {
            good = orders.ToList();
        }

您可以使用通用函数代替 lambda 表达式,但我只是将它们放在一起。此外,您可以构建两个 XDocument,而不是将订单元素放入列表中。我敢肯定这里还有很多其他问题,但也许这会引发一些问题。

于 2009-05-22T18:43:41.100 回答
0

这在很大程度上取决于您的场景中“验证”的含义。我假设,由于您使用的是 .xsd,因此您已经在验证数据在语法上是否正确。那么,验证可能意味着您将调用其他服务或程序来确定订单是否有效?

您可能想查看 Sql Server 集成服务。SSIS 中的 XML 任务允许您执行 XPath 查询、合并等操作,以及您可能需要对该文档执行的任何操作。您也可以将其用于所有带有模式文件的前期验证。

Marc 将该数据传递给存储过程的选项在这种情况下也可能有效,但是 SSIS(或者,甚至是 DTS,但您将放弃与 XML 相关的太多内容以使其成为一个不错的选项)将使您在视觉上协调所有这些工作。另外,它会让这些事情更容易耗尽进程,因此您最终应该得到一个更具可扩展性的解决方案。

于 2008-10-22T15:06:38.477 回答
0

你有几个选择:

  1. XmlDataDocumentXmlDocument。这种方法的缺点是数据将被缓存在内存中,如果你有很多数据,那就不好了。另一方面,您可以使用 DataSet 获得良好的内存查询功能。XmlDocument 要求您使用 XPath 查询来处理数据,而 XmlDataDocument 为您提供更像 DataSet 功能的体验。

  2. xml阅读器。这是一种很好、快速的方法,因为数据没有被缓存;你一次读一点它作为一个流。您从一个元素移动到下一个元素,并在应用程序中查询有关该元素的信息以决定如何处理它。这确实意味着您在应用程序的内存中维护您所在的树级别,但是对于像您这样的简单 XML 文件结构,这应该非常简单。

在您的情况下,我推荐选项 2。它应该在内存使用方面可以很好地扩展,并且应该为处理文件提供最简单的实现。

于 2008-10-22T15:17:51.713 回答
0

通过验证,我的意思是验证每个节点。至少有一个错误的节点需要插入到一个新的 xml 文档中。基本上最后我应该有 2 个 xml 文档。一个包含成功节点,另一个包含失败节点。我有什么办法可以做到这一点?我正在使用 LINQ。

于 2008-10-23T07:16:52.103 回答