2008-10-30 70 views
2

我有一个需要在同一时间拆分XML文档转换成块

它被写在C#中的Windows服务中完成的要处理100个记录大型XML文档。

的结构如下:

<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个订单仍然需要与父“案卷”节点被包裹的,并具有相同的命名空间等

这可能吗?

回答

5

另一个幼稚溶液;这次是.NET 2.0。它应该让你知道如何去做你想要的东西。使用Xpath表达式而不是Linq到XML。在我的开发箱中,将一个100个命令的文档块放入10个dockets中。

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

朴素,迭代,但工程[编辑:在.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; 
    } 
+0

我知道它非常低效。 – 2008-10-30 06:26:57

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 
    }  
}