2010-12-06 3 views
1

Ich habe gerade etwas Code geschrieben, der, wie ich schrieb, ich dachte, dies wird eine nette generische Methode sein, nach einem bestimmten Knoten zu suchen. Als ich fertig war mir klar, eigentlich war es ein Durcheinander: DWie Code neu geschrieben wird, der Knotenliste navigiert

public String sqlReading(String fileName, String path, String nodeId) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(fileName); 

    XmlNodeList names = doc.SelectNodes(path); 
    foreach (XmlNode xmlDocSearchTerm in names) 
    { 
     //if the attribute of the node i start at is the same as where i am now 
     if (xmlDocSearchTerm.Attributes.Item(0).Value.ToString().Equals(nodeId)) 
     { 
      //get a list of all of its child nodes 
      XmlNodeList childNodes = xmlDocSearchTerm.ChildNodes; 

      foreach (XmlNode node in childNodes) 
      { 
       //if there is a node in here called gui display, go inside 
       if (node.Name.Equals("GUIDisplay")) 
       { 
        XmlNodeList list = node.ChildNodes; 
        //find the sqlsearchstring tag inside of here 
        foreach (XmlNode finalNode in list) 
        { 
         if (finalNode.Name.Equals("sqlSearchString")) 
         { 
          return node.InnerText; 
         } 
        } 
       } 
      } 
     } 
    } 
    return ""; 
} 

Was ich gedacht war auf dem Weg zu tun basiert - ich anfangen würde, und prüfen Sie, ob das Element die ID hatte ich suchte, wenn es Dann wollte ich dort reingehen und nicht aufhören, bis ich zu dem sqlsearchstring-Tag kam, der zwei Ebenen tiefer begraben war. Ich habe das geschafft, aber das Problem hier ist, dass ich jetzt scheinbar einen Pfad zum Tag hart codiert habe, der dem Schleifen dort entgegensteht. Wie kann ich meinen Code ändern, um mich davon abzuhalten?

Es ist von der zweiten foreach, wo es falsch geht imo.

Dank

+0

mit XPath, ich glaube, Sie ersetzen können alle 'foreach' Schleifen mit einer einzigen Zeile –

+2

Suchen Sie nach XPath? http://support.microsoft.com/kb/308333 – dsolimano

+0

Haben Sie von XPath gehört? – mjv

Antwort

1

habe es nicht getestet, aber ich glaube, so etwas wie dies funktionieren würde, durch eine XPath. Allerdings bin ich der Name des Attributs nicht sicher, oder ist es immer das erste Attribut?

public String sqlReading(String fileName, String path, String nodeId) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(fileName); 

    XmlNode foundNode = doc.SelectNodes(path).SelectSingleNode("*[@id='" + nodeId + "']/GUIDisplay/sqlSearchString"); 
    if (foundNode != null) 
     return foundNode.InnerText; 
    return string.Empty; 

} 
+0

Das sollte funktionieren, wenn der Name des Zielattributs bekannt ist (oder auch, wenn wir auf _any_attribute mit '" * [@ * = '"' ...) zielen. Wenn jedoch die Anforderung effektiv ist, die Knoten auszuwählen, deren aller erstes Attribut unabhängig von ihrem Namen einen Wert von "nodeId" hat, muss dieses Prädikat _outside_ von XPath entweder in C# (ähnlich der foreach-Schleife von OP) oder in LINQ ausgedrückt werden (ähnlich wie Dean Chalk's Antwort). Mit anderen Worten, während XPath Prädikate basierend auf der Position eines _Node_ [innerhalb seiner Geschwister] anbietet, glaube ich nicht, dass es eine Möglichkeit gibt, die Position eines Attributs anzugeben. – mjv

0

Ich würde sagen, Rekursion eine sichere Wette ist (für Knoten durch verschachtelte Kind Iterieren) Obwohl, von dem, was ich sammeln, bleibt die Struktur die gleiche. Und warum sollten Sie nicht stattdessen (oder ein Faxgerät) verwenden? Dies hat die Fähigkeit, nach Attributnamen zu suchen, es sei denn, die XML-Struktur wird immer geändert, und Sie haben nie eine konstante Markierung (in diesem Fall ist XPath wahrscheinlich eine gute Idee).

1

Ich bin nicht sicher, ob dies exaclty richtig ist (wie ich ein XML-Dokument nicht mit, es zu versuchen, aber etwas Ähnliches soll funktionieren

var innerTexts = XDocument.Load(fileName) 
    .Elements(path) 
    .Where(n => n.Attributes().ElementAt(0).Value == nodeId) 
    .SelectMany(n => n.Elements()) 
    .Where(n => n.Name == "GUIDisplay") 
    .SelectMany(n => n.Elements()) 
    .Where(n => n.Name == "sqlSearchString") 
    .Select(n => n.ToString()); 
Verwandte Themen