2012-11-12 9 views
12

Ho creato un metodo che controlla se esiste un attributo in un file XML. Se non esiste restituisce "False". Funziona ma ci vuole molto tempo per analizzare il file. Sembra che legga l'intero file per ogni singola riga. Ho perso qualcosa qui? Posso renderlo più efficace in qualche modo?Controllo XML parse se esiste l'attributo

public static IEnumerable<RowData> getXML(string XMLpath) 
    { 
     XDocument xmlDoc = XDocument.Load("spec.xml"); 

     var specs = from spec in xmlDoc.Descendants("spec") 
        select new RowData 
        { 
         number= (string)spec.Attribute("nbr"), 
         name= (string)spec.Attribute("name").Value, 
         code = (string)spec.Attribute("code").Value, 
         descr = (string)spec.Attribute("descr").Value, 
         countObject = checkXMLcount(spec), 


     return specs; 
    } 

    public static string checkXMLcount(XElement x) 
    { 
     Console.WriteLine(x.Attribute("nbr").Value); 
     Console.ReadLine(); 
     try 
     { 
      if (x.Attribute("mep_count").Value == null) 
      { 
       return "False"; 
      } 
      else 
      { 
       return x.Attribute("mep_count").Value; 
      } 
     } 
     catch 
     { 
      return "False"; 
     } 
    } 

ho provato a sostituire il metodo con uno che solo i rendimenti e ricevere stringa:

public static string checkXMLcount(string x) 
{ 
    Console.WriteLine(x); 
    Console.ReadLine(); 
    return x; 

} 

Ho fatto un file XML con una sola singola riga. La console stampa il valore 15 volte. Qualche idea?

+0

Perché scrivere la propria versione di XPath, mi chiedo? – raina77ow

risposta

37

risolto! Non è necessario alcun altro metodo:

countObject = spec.Attribute("mep_count") != null ? spec.Attribute("mep_count").Value : "False", 
+2

Se ne hai molti ... puoi incapsulare ....... stringa privata SafeAttributeValue (XAttribute xattr) { string returnValue = string.Empty; if (null! = Xattr) { returnValue = (stringa) xattr.Value; } return returnValue; } – granadaCoder

2

Si può provare questo e vedere se c'è qualche miglioramento

class xmlAttributes 
{ 
    public string Node; 
    public Dictionary<string, string> Attributes; 
} 

Ora, con questo LINQ, tutti gli attributi sono memorizzati in un dizionario (per nodo) e potrebbero essere accessibili tramite il nome dell'attributo.

var Result = XElement.Load("somedata.xml").Descendants("spec") 
         .Select(x => new xmlAttributes 
         { 
          Node = x.Name.LocalName, 
          Attributes = x.Attributes() 
            .ToDictionary(i => i.Name.LocalName, 
                 j => j.Value) 
         }); 

Controlla se esiste un attributo su tutti i nodi XML

var AttributeFound = Result.All(x => x.Attributes.ContainsKey("AttrName")); 

Controlli se l'attributo appare almeno una volta

var AttributeFound = Result.Any(x => x.Attributes.ContainsKey("AttrName"));