2016-06-02 12 views
2

ich unter XML-Datei haben:lesen sich wiederholende Blöcke mit XmlReader C#

<PackList> 
    <Header> 
    <OrderNumber>PO12123</OrderNumber> 
    <OrderQty>100</OrderQty> 
    </Header> 
    <Items> 
    <Item> 
     <PN>31023312</PN> 
     <Color>Black</Color> 
    </Item> 
    <Item> 
     <PN>22023312</PN> 
     <Color>White</Color> 
    </Item> 
    <Item> 
     <PN>44023312</PN> 
     <Color>Blue</Color> 
    </Item> 
    </Items> 
</PackList> 

Ich bin in der Lage, die Header Teil mit folgenden Code zu lesen:

public class OrderItem 
{ 
    public string PN { get; set; } 
    public string Color { get; set; } 
} 

public class PList 
{ 
    public string OrderNumber { get; set; } 
    public int OrderQty { get; set; } 
    public List<OrderItem> OrderItems = new List<OrderItem>(); 
} 

(...) 
PList PL = new PList(); 
using (XmlReader reader = XmlReader.Create(@"c:/Test/PackList.xml")) 
{ 
    reader.ReadToFollowing("OrderNumber"); 
    PList.OrderNumber = reader.ReadElementContentAsString(); 
    reader.ReadToFollowing("OrderQty"); 
    PList.OrderQty = reader.ReadElementContentAsInt(); 
} 
(...) 

Aber ich habe keine Ahnung, wie man lesen Sie alle Item innerhalb des Tags Items.

Irgendwelche Ratschläge?

+0

Linq (von Xml zu DTO) ist viel einfacher als XmlReader. Ist das Quelldokument riesig? Oder kannst du das ganze XML in den Speicher laden? Wenn ja, siehe diesen Beitrag: http://stackoverflow.com/questions/18498467/parent-children-xml-to-dto-object-model-with-linq – granadaCoder

+0

Es könnte sehr groß sein. – Somebody

+0

Ich benutze meine Antwort wie folgt. Ich verwende eine Kombination aus XmlReader und Xml Linq. http://stackoverflow.com/questions/37503602/efficient-parsing-of-xml/37503653#37503653 – jdweng

Antwort

1
reader.ReadToFollowing("OrderNumber"); 
plist.OrderNumber = reader.ReadElementContentAsString(); 
reader.ReadToFollowing("OrderQty"); 
plist.OrderQty = reader.ReadElementContentAsInt(); 

reader.ReadToFollowing("Items"); 

using (var innerReader = reader.ReadSubtree()) 
{ 
    while (innerReader.ReadToFollowing("PN")) 
    { 
     var item = new OrderItem(); 
     item.PN = innerReader.ReadElementContentAsString(); 
     reader.ReadToFollowing("Color"); 
     item.Color = innerReader.ReadElementContentAsString(); 

     plist.OrderItems.Add(item); 
    } 
} 

reader.ReadToFollowing("foo"); 
var foo = reader.ReadElementContentAsString(); 

Wo foo Tag-Namen nach dem Items ist.

Vergessen Sie nicht plist.OrderItems = new List<OrderItem>();

+0

Ich testete den gleichen Ansatz, den Sie gepostet haben, es funktioniert gut. Wenn jedoch nach den Elementen ein anderes Tag vorhanden ist (nicht der Fall, der gepostet wurde), wird es seit ReadToFollowing ("PN") nicht gelesen, wenn false, der XmlReader am Ende des Dateizustands ist. – Somebody

+0

@Somebody - siehe Update –

0

Verwenden XmlNodeList

XmlDocument document = new XmlDocument(); 

document.Load(@"c:/Test/PackList.xml"); 

XmlNodeList Items = document.GetElementsByTagName("Item"); 

foreach (XmlNode item in Items) 
{ 
    // do something 
} 
+0

Dies zieht das gesamte Dokument in den Speicher. XmlReader ist der "Firehose" Weg. – granadaCoder

+0

Ich wollte es mit XmlReader tun, wenn möglich. – Somebody

Verwandte Themen