2016-08-05 18 views
0

Ich habe eine xml Datei, die wie folgt aussieht. Und ich möchte eine Methode erstellen, die mir den Wert mit dem Schlüssel bringen würde.XML - C# Generische Methode zum Abrufen eines Werts mit einem Schlüssel auf einem serialisierten Objekt

</cbn:Class> 
     <cbt:Students> 
      <cbt:Student> 
      <cbt:Key>x-param-key-studentName-1</cbt:Key> 
      <cbt:Value>x-param-studentSurname-val</cbt:Value> 
      </cbt:Student> 
      <cbt:Student> 
      <cbt:Key>x-param-key-studentName-2</cbt:Key> 
      <cbt:Value>x-param- studentSurname-val</cbt:Value> 
      </cbt:Student> 
     </cbt:Students> 
    </cbn:Class> 

Also, ich möchte die valud von studentSurname als Schlüssel der studentName mit bekommen. Die xml ist serialisiert, so kann ich zB auf den Student als Objekt zugreifen. Ich kann den Wert des ersten Schüler erhalten, indem Sie den Code verwenden ich geschrieben habe, wie unten:

string studentSurname = myData.Class.Students.Student[0].Value; 

Wo myData das serialisierte Objekt ist. Ich hätte gerne eine allgemeinere Methode, anstatt nur den ersten Schüler zu bekommen.
EDIT:Eine andere XML

<?xml version="1.0" encoding="UTF-8"?> 
<cbn:PaidOrderNotification xmlns:cbn="http://*/3.12.0.0/*.xsd"> 
    <cbn:NotificationDate>2016-07-29T11:59:29.1137865Z</cbn:NotificationDate> 
    <cbn:Purchase cbt:Id="95233035" xmlns:cbt="http://xml.*.com/3.12.0.0/*.xsd"> 
     <cbt:Status>Test Order</cbt:Status> 
     <cbt:StatusId>TST</cbt:StatusId> 
     <cbt:Items> 
      <cbt:Item cbt:RunningNo="1"> 
       <cbt:ProductId>175358</cbt:ProductId> 
       <cbt:ProductReportingGroup>Basic alle Laufzeiten</cbt:ProductReportingGroup> 
       <cbt:YourCurrencyId>EUR</cbt:YourCurrencyId> 
       <cbt:ProfitCalculation> 
        <cbt:GrossRevenue>566.44</cbt:GrossRevenue> 
       </cbt:ProfitCalculation> 
       <cbt:YourPrice> 
        <cbt:TotalTotalPrice> 
        </cbt:TotalTotalPrice> 
       </cbt:YourPrice> 
       <cbt:Deliveries /> 
       <cbt:Additionals /> 
       <cbt:ExtraParameters /> 
      </cbt:Item> 
     </cbt:Items> 
     <cbt:ExtraParameters> 
      <cbt:ExtraParameter> 
       <cbt:Key>x-my-key</cbt:Key> 
       <cbt:Value> x-my-val</cbt:Value> 
      </cbt:ExtraParameter> 
     </cbt:ExtraParameters> 
    </cbn:Purchase> 
</cbn:PaidOrderNotification> 

ich von hier aus diesem Wert nehmen möchte:

<cbt:ExtraParameters> 
      <cbt:ExtraParameter> 
       <cbt:Key>x-didi</cbt:Key> 
       <cbt:Value>sfsfd</cbt:Value> 
      </cbt:ExtraParameter> 
     </cbt:ExtraParameters> 

Wie kann ich das tun?

+3

funktioniert. Ihr XML ist ungültig. In Zeile 3 öffnen Sie '', aber in Zeile 6 schließen Sie ''. Du hast diese nicht geöffnet und du hast den Schüler nicht geschlossen. – Bobby

+0

Sorry, Sie @ManuToMatic haben Recht, ich habe vergessen, das vor dem Senden des Codes zu ändern. Ich habe jetzt bearbeitet :) – eg16

Antwort

1

Ihr XML-Dokument hat Namespaces, aber Ihr Beispiel enthält es nicht, musste ich einige Werte vortäuschen.

Sobald Sie die URI für die Namensräumen haben Sie eine XmlNamespaceManager mit dem entsprechenden Qualifikationsspiel in das Dokument suchen

var xml = @" 
    <cbn:Class xmlns:cbn='something' xmlns:cbt='something-else'> 
     <cbt:StudentNr></cbt:StudentNr> 
     <cbt:Students> 
      <cbt:Student> 
       <cbt:Key>x-param-key-studentName-1</cbt:Key> 
       <cbt:Value>x-param-studentSurname-val</cbt:Value> 
      </cbt:Student> 
      <cbt:Student> 
       <cbt:Key>x-param-key-studentName-2</cbt:Key> 
       <cbt:Value>x-param- studentSurname-val</cbt:Value> 
      </cbt:Student> 
     </cbt:Students> 
    </cbn:Class>"; 

var doc = new XmlDocument(); 
    doc.LoadXml(xml); 

var students = doc.SelectSingleNode("//*[local-name() = 'Students']"); 
var nsmgr = new XmlNamespaceManager(doc.NameTable); 
    nsmgr.AddNamespace("cbt", students.NamespaceURI); 

var dictionary = students.SelectNodes("cbt:Student", nsmgr).OfType<XmlElement>() 
    .ToDictionary(student => student.SelectSingleNode("cbt:Key" , nsmgr).InnerText, 
        student => student.SelectSingleNode("cbt:Value", nsmgr).InnerText); 

EDIT verwenden können: Sie tun können, dies auch:

string studentSurname = ""; 
var dictionary = myData.Class.Students.ToDictionary(student => student.Key, 
                student => student.Value); 
var exists = dictionary.TryGetValue("x-param-key-studentName-1", out studentSurname); 

EDIT2: Beachten Sie, dass Sie zwei verschiedene cbt:ExtraParameters Elemente haben, und das erste ist leer. Ich habe den Code so erweitert, dass er mit allen cbt:ExtraParameter Elementen

var doc = new XmlDocument(); 
    doc.LoadXml(xml); 

var dictionary = doc.SelectNodes("//*[local-name() = 'ExtraParameter']") 
    .OfType<XmlElement>() 
    .ToDictionary(
     extra => extra.SelectSingleNode("*[local-name() = 'Key' ]").InnerText, 
     extra => extra.SelectSingleNode("*[local-name() = 'Value']").InnerText 
    ); 

var studentSurname = ""; 
var exists = dictionary.TryGetValue("x-my-key", out studentSurname); 
+0

Der Count von var _extraParameters = doc.SelectSingleNode ("// * [local-name() = 'ExtraParameters']"); ist 0, obwohl ich einen solchen Knoten in meinem XML habe. – eg16

+1

Dieser Knoten ist in Ihrem Beispiel nicht vorhanden; Wie auch immer, passen Sie auf die XML-Groß- und Kleinschreibung auf –

+0

Entschuldigung, die sein sollte: _extraParameters = doc.SelectSingleNode ("// * [local-name() = 'Students']"); Es war mein Fehler auf den Kommentar – eg16