这是交易。我有一个包含大量记录的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个插入.2。一个xml文件中可能有数千条记录。这里最好的方法是什么。由于我需要丢弃失败的记录并且仅使用通过验证的记录,因此验证将如何进行验证。目前我正在使用 XmlReaderSettings 来验证XML文档记录。在插入数据库之前,是否应将这些记录提取到另一个XML文件或数据集或自定义对象中。我正在使用.Net 3.5。欢迎任何代码或链接。
答案 0 :(得分:1)
如果数据相当干净地映射到对象模型,您可以尝试使用xsd.exe从.xsd生成一些类,并将类处理到您选择的DAL中。问题是,如果音量很高(你提到数千条记录),你很可能会有往返的批次。
另一种选择可能是将数据“按原样”传递到数据库并使用SQL / XML处理TSQL中的数据 - 可能是作为接受xml类型的参数(SQL Server 2005等)的存储过程。
答案 1 :(得分: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表达式,但我只是将它们放在一起。此外,您可以构建两个XDocuments,而不是将订单元素推送到列表中。我相信这里也存在很多其他问题,但也许这会引发一些问题。
答案 2 :(得分:0)
很多都取决于您的方案中“验证”的含义。我假设,因为您使用的是.xsd,所以您已经在验证数据在语法上是否正确。 因此,验证可能意味着您将调用其他服务或程序来确定订单是否有效?
您可能希望查看Sql Server Integration Services。 SSIS中的XML任务允许您执行XPath查询,合并,可能的任何事情以及您需要对该文档执行的所有操作。您也可以使用它来完成对模式文件的所有前期验证。
Marc将这些数据传递给存储过程的选择也可能在这种情况下有效,但是SSIS(或者,甚至是DTS,但是你将放弃太多与XML相关的东西以使其成为一个不错的选项)让你在视觉上协调所有这些工作。此外,它还可以使这些事情更容易用完,因此您最终可以获得更具可扩展性的解决方案。
答案 3 :(得分:0)
您有几个选择:
XmlDataDocument或XmlDocument。这种方法的缺点是数据将被缓存在内存中,如果你有很多数据,那就很糟糕。另一方面,您可以使用DataSet获得良好的内存查询功能。 XmlDocument要求您使用XPath查询来处理数据,而XmlDataDocument为您提供更像DataSet功能的体验。
XmlReader。这是一种好的,快速的方法,因为数据没有被缓存;你一次把它作为一个流读取。您从一个元素移动到下一个元素,并在应用程序中查询有关该元素的信息,以决定如何处理它。这意味着您在应用程序的内存中保留了您所在的树级别,但是使用与您类似的简单XML文件结构,这应该非常简单。
我推荐你选择2。它应该在内存使用方面很好地扩展,并且应该提供最简单的处理文件的实现。
答案 4 :(得分:0)
通过验证,我的意思是验证每个节点。需要将至少有一个错误的节点插入到新的xml文档中。基本上最后我应该有2个xml文件。一个包含成功节点,另一个包含故障节点。我能做到的任何方式吗?我正在使用LINQ。