2012-04-09 4 views
2

ich in einer XML-Datei suchen, die wie folgt aussieht: Ich habeLinq to XML ohne zu wissen, wie viele Nachkommen gibt es

<test> 
    <vehiclenumber>123</vehiclenumber> 
    <form> 
    <form_id>1</form_id> 
    <datafield> 
     <fieldnumber>1</fieldnumber> 
     <data> 
      <datawords> 
       <datatext1>1234</datatext1> 
       <mc2>656865</mc2> 
      </datawords> 
     </data> 
     </datafield> 
    </form> 
</test> 

Zeit den folgenden Code:

IEnumerable<XElement> elements = documentXDoc.Descendants("test"); 

      _fuelReceipts.AddRange(elements 
       .Select(receipt => new Receipt() 
       { 
        vehicle_number = receipt.Element("vehiclenumber") == null ? "" : receipt.Element("vehiclenumber").Value, 
        field = receipt.Descendants("datafield") 
        .Select(x => new Field() 
        { 
         field_number = x.Element("fieldnumber") == null ? "" : x.Element("fieldnumber").Value, 
         event_data = x.Descendants("data") 
         .Select(y => new FieldData() 
         { 
          event_data = y.Value 
         }).ToList() 
        }).ToList() 
       })); 
     } 

Das Problem hier ist, dass für die <data> ich nicht weiß, wie viele Nachkommen werden dort sein oder wie sie genannt werden. Gibt es eine Möglichkeit, diese separat zu analysieren, ohne diese Informationen zu kennen? Im Moment würde ich etwas wie 1234656865 bekommen, wenn ich eigentlich 1234 in einem Objekt und 656865 in einem separaten Objekt haben möchte.

Antwort

1

Ihre inneren „Daten“ ändern zu, dass wählen:

event_data = x.Descendants("data").Descendants().Where(d => !d.HasElements).Select(y => y.Value).ToList() 

Dadurch wird eine Liste von string mit zwei Elementen geben: 1234 und 656865. Sie können es leicht zu einer Zeichenfolge mit String.Join() Methode beitreten:

event_data = String.Join(" ", x.Descendants("data").Descendants().Where(d => !d.HasElements).Select(y => y.Value).ToList()) 
+0

Wenn ich dies tue, bekomme ich am Ende eine Fehlermeldung auf der ToList(). Es versucht, eine generic.list in mein Geschäftsobjekt zu konvertieren. Im Moment ist das Geschäftsobjekt nur öffentliche Zeichenfolge event_data {get; einstellen; }, was sollte es sein, damit dies funktioniert? – mameesh

+0

Ich habe meine Antwort bearbeitet. 'event_data' sollte' List 'oder' IEnumerable 'sein. Wenn Sie nur eine Zeichenfolge mit Leerzeichen als Trennzeichen möchten, verwenden Sie das zweite Beispiel mit 'String.Join()' – MarcinJuraszek

1

Ich nehme an, dass die Namen der XML-Nachkommen sinnvoll sind. Dieser Code fügt sie in ein Dictionary ein, wenn sie in das Field-Objekt extrahiert werden.

void Main() 
{ 
    string input = "<test><vehiclenumber>123</vehiclenumber><form><form_id>1</form_id><datafield>"; 
    input += "<fieldnumber>1</fieldnumber><data><datawords>"; 
    input += "<datatext1>1234</datatext1><mc2>656865</mc2>"; 
    input += "</datawords></data></datafield></form></test>"; 

    XDocument documentXDoc = XDocument.Parse(input); 
    IEnumerable<XElement> elements = documentXDoc.Descendants("test"); 

    IEnumerable<Receipt> _fuelReceipts = elements 
     .Select(receipt => new Receipt() 
     { 
      vehicle_number = receipt.Element("vehiclenumber") == null ? "" : receipt.Element("vehiclenumber").Value, 
      field = receipt.Descendants("datafield") 
      .Select(x => new Field() 
      { 
       field_number = x.Element("fieldnumber") == null ? "" : x.Element("fieldnumber").Value, 
       event_data = x.Elements("data").Descendants() 
        .Where(d => !d.HasElements) 
        .ToDictionary(d => d.Name.LocalName, d => d.Value) 
      }).ToList() 
     }); 
} 

class Receipt { 
    public string vehicle_number { get; set; } 
    public List<Field> field { get; set; } 
} 

class Field { 
    public string field_number { get; set; } 
    public Dictionary<string, string> event_data { get; set; } 
}