2008-10-30 97 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 
    }  
}