我有一个大型xml文档,需要一次处理100条记录
它是在用c#编写的Windows服务中完成的。
结构如下:
<docket xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="docket.xsd">
<order>
<Date>2008-10-13</Date>
<orderNumber>050758023</orderNumber>
<ParcelID/>
<CustomerName>sddsf</CustomerName>
<DeliveryName>dsfd</DeliveryName>
<Address1>sdf</Address1>
<Address2>sdfsdd</Address2>
<Address3>sdfdsfdf</Address3>
<Address4>dffddf</Address4>
<PostCode/>
</order>
<order>
<Date>2008-10-13</Date>
<orderNumber>050758023</orderNumber>
<ParcelID/>
<CustomerName>sddsf</CustomerName>
<DeliveryName>dsfd</DeliveryName>
<Address1>sdf</Address1>
<Address2>sdfsdd</Address2>
<Address3>sdfdsfdf</Address3>
<Address4>dffddf</Address4>
<PostCode/>
</order>
.....
.....
</docket>
备案中可能有数千份订单。
我需要将其切成100个元素块
然而,100个订单中的每一个仍然需要用父“docket”节点包装并具有相同的命名空间等
这可能吗?答案 0 :(得分:5)
另一个天真的解决方案;这次适用于.NET 2.0。它应该让你知道如何去做你想要的。使用Xpath表达式而不是Linq to XML。在我的devbox上,在一秒钟内将100个订单分成10个小册子。
public List<XmlDocument> ChunkDocket(XmlDocument docket, int chunkSize)
{
List<XmlDocument> newDockets = new List<XmlDocument>();
//
int orderCount = docket.SelectNodes("//docket/order").Count;
int chunkStart = 0;
XmlDocument newDocket = null;
XmlElement root = null;
XmlNodeList chunk = null;
while (chunkStart < orderCount)
{
newDocket = new XmlDocument();
root = newDocket.CreateElement("docket");
newDocket.AppendChild(root);
chunk = docket.SelectNodes(String.Format("//docket/order[position() > {0} and position() <= {1}]", chunkStart, chunkStart + chunkSize));
chunkStart += chunkSize;
XmlNode targetNode = null;
foreach (XmlNode c in chunk)
{
targetNode = newDocket.ImportNode(c, true);
root.AppendChild(targetNode);
}
newDockets.Add(newDocket);
}
return newDockets;
}
答案 1 :(得分:1)
天真,迭代,但有效[编辑:仅在.NET 3.5中]
public List<XDocument> ChunkDocket(XDocument docket, int chunkSize)
{
var newDockets = new List<XDocument>();
var d = new XDocument(docket);
var orders = d.Root.Elements("order");
XDocument newDocket = null;
do
{
newDocket = new XDocument(new XElement("docket"));
var chunk = orders.Take(chunkSize);
newDocket.Root.Add(chunk);
chunk.Remove();
newDockets.Add(newDocket);
} while (orders.Any());
return newDockets;
}
答案 2 :(得分:0)
如果一次处理100个订单的原因是出于性能目的,例如花费太多时间和资源来打开一个大文件,您可以利用XmlReader一次处理一个订单元素,而不会降低性能。
XmlReader reader = XmlReader.Create(@"c:\foo\Doket.xml")
while( reader.Read())
{
if(reader.LocalName == "order")
{
// read each child element and its value from the reader.
// or you can deserialize the order element by using a XmlSerializer and Order class
}
}