2016-04-01 5 views
2

Ich habe hier eine Variablen-Zeichenfolge mit dem Namen OutputKSZ, die den Code einer XML-Datei enthält. Der Code dieser XML-Datei enthält variable Mengen des Tags <streetName language = "EN"> gefolgt von einem vollständig variablen Straßennamen und dann </streetName>.C# Alle Vorkommen innerhalb der Variablen-Zeichenfolge in der Combobox anzeigen

Jetzt habe ich auch eine winforms winzige Anwendung, mit einem Textfeld, einer Schaltfläche und einer Combobox. In der Textbox kopiere ich den XML-Code. Dann klicke ich auf den Knopf, und die Combobox sollte mir eine Liste aller verschiedenen Straßennamen zwischen jedem <streetName language = "EN"></streetName> Tag geben.

Also, für alle Klarheit, gibt es zwei variable Dinge hier:

  1. die Menge des Vorkommens des Tags streetName
  2. die Länge jede Zeichenfolge zwischen jedem streetName-Tag.

Das ist, was ich bisher ausprobiert habe:

dort
if (OutputKSZ.Contains("<address source=\"")) 
{ 
    // LIJST MET START INDEXES 
    List<int> indexesStart = new List<int>(); 
    var AddressSourceStart = new Regex("<streetName language=\"EN\">"); 
    foreach (Match match in AddressSourceStart.Matches(OutputKSZ)) 
    { indexesStart.Add(match.Index); } 

    // LIJST MET END INDEXES 
    List<int> indexesEnd = new List<int>(); 
    var AddressSourceEnd = new Regex("</streetName>"); 
    foreach (Match match in AddressSourceEnd.Matches(OutputKSZ)) 
    { indexesEnd.Add(match.Index); } 

    int[] counterI = Enumerable.Range(0, indexesStart.Count).ToArray(); 
    foreach (int i in counterI) 
    { 
     int KSZGedeelteStraatStart = indexesStart[i]; 
     int KSZGedeelteStraatEnd = indexesEnd[i]; 
     int KSZGedeelteStraatLength = KSZGedeelteStraatEnd - KSZGedeelteStraatStart - 26; 
     string KSZGedeelteStraat = OutputKSZ.Substring(KSZGedeelteStraatStart + 26, KSZGedeelteStraatLength); 
     foreach (int ListCounter in counterI) 
     { 
      List<string> ListKSZGedeelteStraat = new List<string>(); 
      ListKSZGedeelteStraat.Add(KSZGedeelteStraat); 
      comboBox2.DataSource = ListKSZGedeelteStraat; 
     } 

    } 

Sorry für die Holländer. ;)
Das Problem mit diesem Code ist, dass es nur das allerletzte Auftreten zeigt, und ich bin wirklich frisch aus Ideen, ich habe stundenlang auf diese gewesen.

Habt ihr irgendwelche Ideen, wie Sie das korrigieren können? Ich bin ziemlich neu in C#, solange ich die Textbox, den Button und die Combobox habe, kann ich meinen ganzen Code neu schreiben, wenn es sein muss.

XML-Beispiel:

<soapenv:Envelope> 
    <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" /> 
    <soapenv:Body> 
    <external:searchPersonInformationHistoryBySsinResponse> 
     <informationCustomer> 
     <customerIdentification> 
      <sector>15</sector> 
      <institution>5</institution> 
     </customerIdentification> 
     </informationCustomer> 
     <informationCBSS> 
     <ticketCBSS>b2d07603-2205-4258-b3b9-49320ab4b919</ticketCBSS> 
     <timestampReceive>2016-03-27T12:49:59.680Z</timestampReceive> 
     <timestampReply>2016-03-27T12:50:00.072Z</timestampReply> 
     </informationCBSS> 
     <legalContext>NISSE:IDENTIFICATION</legalContext> 
     <criteria> 
     <ssin>somenumber</ssin> 
     <datagroups> 
      <addresses>true</addresses> 
     </datagroups> 
     </criteria> 
     <status> 
     <value>DATA_FOUND</value> 
     <code>MSG00000</code> 
     <description>Successful</description> 
     </status> 
     <result> 
     <person register="RR"> 
      <ssin>somenumber</ssin> 
      <addresses status="DATA_FOUND"> 
      <address source="NR"> 
       <residentialAddress> 
       <countryCode>150</countryCode> 
       <countryName language="FR">Belgique</countryName> 
       <countryName language="NL">België</countryName> 
       <countryName language="DE">Belgien</countryName> 
       <cityCode>somecitycode</cityCode> 
       <cityName language="NL">somecityname</cityName> 
       <postalCode>somepostalcode</postalCode> 
       <streetCode>somestreetcode</streetCode> 
       <streetName language="NL">somestreetname</streetName> 
       <houseNumber>2</houseNumber> 
       <inceptionDate>2014-08-09</inceptionDate> 
       </residentialAddress> 
      </address> 
      <address source="NR"> 
       <residentialAddress> 
       <countryCode>150</countryCode> 
       <countryName language="FR">Belgique</countryName> 
       <countryName language="NL">België</countryName> 
       <countryName language="DE">Belgien</countryName> 
       <cityCode>someothercitycode</cityCode> 
       <cityName language="NL">someothercityname</cityName> 
       <postalCode>someotherpostalcode</postalCode> 
       <streetCode>someotherstreetcode</streetCode> 
       <streetName language="NL">someotherstreetname</streetName> 
       <houseNumber>2</houseNumber> 
       <inceptionDate>2014-08-09</inceptionDate> 
       </residentialAddress> 
      </address> 
      </addresses> 
     </person> 
     </result> 
    </external:searchPersonInformationHistoryBySsinResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 
+0

Sie sollten einen [XML-Reader] (https://msdn.microsoft.com/en-us/library/cc189056 (v = vs.95) .aspx) verwenden, um die Suche zu vereinfachen. –

+0

Bitte zeigen Sie uns einige Beispieldaten an. (Beispiel: Beispiel-XML-Zeichenfolge, die Sie verwenden) –

+0

Ich werde irgendwann in der Zukunft in den XML-Reader schauen, aber da ich wenig über XML-Dateien weiß (ich kann sie erkennen, aber darum geht es), würde ich gerne lösen Dieses Problem ohne XML-Reader. – SomebodyWithAQuestion

Antwort

1

Ihre Loop-Integration ist ein bisschen aus.

Versuchen Sie dies (enthalten einige Testdaten, entfernen Sie nach Belieben).

string OutputKSZ = "<address source=\">" + 
           "<streetName language=\"EN\">1</streetName> " + 
           "<streetName language=\"EN\">12</streetName> " + 
           "<streetName language=\"EN\">111</streetName> " 
           ; 

      //Moved for scoping purposes 
      List<string> ListKSZGedeelteStraat = new List<string>(); 

      if (OutputKSZ.Contains("<address source=\"")) 
      { 
       // LIJST MET START INDEXES 
       List<int> indexesStart = new List<int>(); 
       var AddressSourceStart = new Regex("<streetName language=\"EN\">"); 
       foreach (Match match in AddressSourceStart.Matches(OutputKSZ)) 
       { 
        indexesStart.Add(match.Index); 
       } 

       // LIJST MET END INDEXES 
       List<int> indexesEnd = new List<int>(); 
       var AddressSourceEnd = new Regex("</streetName>"); 
       foreach (Match match in AddressSourceEnd.Matches(OutputKSZ)) 
       { 
        indexesEnd.Add(match.Index); 
       } 

       int[] counterI = Enumerable.Range(0, indexesStart.Count).ToArray(); 
       foreach (int i in counterI) 
       { 
        int KSZGedeelteStraatStart = indexesStart[i]; 
        int KSZGedeelteStraatEnd = indexesEnd[i]; 
        int KSZGedeelteStraatLength = KSZGedeelteStraatEnd - KSZGedeelteStraatStart - 26; 
        string KSZGedeelteStraat = OutputKSZ.Substring(KSZGedeelteStraatStart + 26, KSZGedeelteStraatLength); 

        //Remove additional foreach loop - you were adding too many times 
        ListKSZGedeelteStraat.Add(KSZGedeelteStraat); 
       } 

       //Assign data source once 
       comboBox2.DataSource = ListKSZGedeelteStraat; 
      } 
+0

Vielen Dank so sehr! Ich habe dank dieses Codes etwas anderes zum Laufen bekommen. – SomebodyWithAQuestion

2

Wenn es keinen Grund gibt, nicht den XML analysieren ich es zu einem XDocument laden würde und ein basisches LINQ query wie folgt verwenden:

var OutputKSZ = textBox1.Text; 

var xdocument = XDocument.Parse(OutputKSZ); 

var streets = xdocument.Descendants("streetName"); 

var streetNames = streets.Select(s => s.Value).ToList(); 

comboBox2.DataSource = streetNames; 

Dieses won‘ t funktionieren, wenn die Daten kein gültiges xml sind.

+0

PERFEKT gearbeitet! Vielen Dank! :) – SomebodyWithAQuestion

0

Dies ist eine gute Möglichkeit, mit LINQ zu bekommen, was Sie brauchen. Stecken Sie diesen in LinqPad es auszuprobieren:

void Main() 
{ 
    XElement contacts = 
    new XElement("Contacts", 
    new XElement("Contact", 
     new XElement("Name", "Patrick Hines"), 
     new XElement("Address", 
      new XElement("streetName", "Linden Strass", 
       new XAttribute("language", "EN")), 
      new XElement("City", "Mercer Island"), 
      new XElement("State", "WA"), 
      new XElement("Postal", "68042") 
     ) 
    ), 
     new XElement("Contact", 
     new XElement("Name", "Max Dane"), 
     new XElement("Address", 
      new XElement("streetName", "Marten Strass", 
       new XAttribute("language", "EN")), 
      new XElement("City", "Mercer Island"), 
      new XElement("State", "WA"), 
      new XElement("Postal", "68042") 
     ) 
    ) 
    ); 

    var streets = contacts.Elements("Contact").Elements("Address").Elements("streetName") 
          .Where(c => (string)c.Attribute("language") == "EN").ToList(); 

    streets.Dump(); 

    // Another way to express this getting all elements of that name 
    var streets2 = contacts.Descendants("streetName") 
         .Where(c => (string)c.Attribute("language") == "EN").ToList(); 

    streets2.Dump(); 
} 
0

Ich würde versuchen, einen anderen Ansatz mit RegEx und Spielen. Das Problem ist, dass es vielleicht nicht die eleganteste Lösung ist.

Ich habe etwas Forschung und ich fand this. Dort wird erklärt, wie eine Zeichenkette zwischen zwei bekannten Tags abgerufen wird.

Hier ist die Funktion, um die Straßennamen abzurufen:

List<string> extractString(string xmldata){ 
    Regex regex = new Regex("<streetName language = \"EN\">(.*?)</streetName>"); 
    MatchCollection streetCollection = regex.Matches(xmldata); 

    //Total number of matches=streetCollection.count 
    List<string> streetList = new List<string>(); 
    for(int i=0;i<streetCollection.count;i++){ 
     streetList.Add(streetCollection[ctr].Value); 
    } 

    return streetList; 
} 

Ich denke, es ist so etwas wie dieses wäre. Ich bin mir über die Grammatik nicht völlig sicher, da ich mich nicht in meinem sich entwickelnden Computer befinde, also hatte ich keine Möglichkeit, den Code selbst zu überprüfen. Aber das könnte ein Anfang sein.Sag mir, wenn du Fehler oder etwas bekommst.