2008-10-22 71 views
1

这是交易。我有一个有很多记录的XML文档。类似这样的:通过记录验证和提取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插入到数据库中,并将其他2个存储。在一个XML文件中可以存储数千个记录。这里最好的办法是什么?验证将如何进行,因为我需要放弃失败的记录,只使用通过验证的记录。目前,我正在使用XmlReaderSettings来验证XML文档记录。在插入数据库之前,我应该将这些记录提取到另一个XML文件或数据集或自定义对象中。我正在使用.Net 3.5。任何代码或链接是受欢迎的。

回答

0

你有两个选择:

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

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

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

1

如果数据完全干净地映射到对象模型,可以尝试使用xsd.exe从.xsd生成一些类,然后将这些类处理到您选择的DAL中。问题是,如果数量很高(你提到了数千条记录),你很有可能会有一个往返行程。

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

+0

SQL部分是可扩展的。 – scarpacci 2011-10-29 14:22:41

0

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

您可能想看看Sql Server Integration Services。 SSIS中的XML任务可以让你执行诸如XPath查询,合并,可能任何事情以及你需要处理该文档的所有事情。您也可以将它用于模式文件的所有前期验证。

Marc将这些数据传递给存储过程的选项也可能适用于这种情况,但是SSIS(或者甚至DTS,但是您将放弃太多与XML相关的选项)将让你可视化地编排所有这些工作。此外,它将使这些事情更容易地用完,因此您最终应该拥有更具可扩展性的解决方案。

0

通过验证我的意思是验证每个节点。至少有一个错误的节点需要插入到一个新的xml文档中。基本上最后我应该有2个XML文件。一个包含成功的节点,另一个包含故障节点。任何方式,我可以做到这一点?我正在使用LINQ。

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,而不是将订单元素放入列表中。我相信这里也有很多其他问题,但也许这会引发一些问题。

+0

+1用于验证Schema并使用Linq/Lambda – scarpacci 2011-10-29 14:22:09