2012-05-24 3 views
8

Ho un file di configurazione personalizzato.Ottieni gli attributi Nome e Valore dell'elemento in C# tramite System.Linq

<Students> 
<student> 
    <Detail Name="abc" Class="1st Year"> 
     <add key="Main" value="web"/> 
     <add key="Optional" value="database"/> 
    </Detail> 
</student> 
</Students> 

Ho letto questo file tramite l'implementazione dell'interfaccia IConfigurationHandler. Quando leggo gli attributi childNode dell'elemento Detail. Mi restituisce sotto il risultato in Immediate Window di IDE.

elem.Attributes.ToObjectArray() 

{object[2]} 
    [0]: {Attribute, Name="key", Value="Main"} 
    [1]: {Attribute, Name="value", Value="web"} 

Quando tento di scrivere su Console

Console.WriteLine("Value '{0}'",elem.Attributes.ToObjectArray()); 

mi fa ritorno

metodo
Value : 'System.Configuration.ConfigXmlAttribute' 

elem.Attributes.Item(1) mi dà il nome e Valore dettaglio, ma qui ho bisogno di passare il valore dell'indice di attributo che non conosco attualmente.

voglio ottenere nome e il valore dell'attributo attraverso query LINQ e display sul Console per ogni attributo childNode come segue:

Value : Name="Key" and Value="Main" 
     Name="value", Value="web" 

Come posso raggiungere questo obiettivo?

+0

Come lo migliorerò. –

+0

Che cosa stai cercando di fare qui? Risolve la console.Writeline? Puoi pubblicare più del tuo codice in modo che possiamo capire il flusso? – Jake1164

risposta

3

Se si desidera utilizzare questo Xml Library è possibile ottenere tutti gli studenti e le loro informazioni con questo codice:

XElement root = XElement.Load(file); // or .Parse(string) 
var students = root.Elements("student").Select(s => new 
{ 
    Name = s.Get("Detail/Name", string.Empty), 
    Class = s.Get("Detail/Class", string.Empty), 
    Items = s.GetElements("Detail/add").Select(add => new 
    { 
     Key = add.Get("key", string.Empty), 
     Value = add.Get("value", string.Empty) 
    }).ToArray() 
}).ToArray(); 

Poi a scorrere su di usarli:

foreach(var student in students) 
{ 
    Console.WriteLine(string.Format("{0}: {1}", student.Name, student.Class)); 
    foreach(var item in student.Items) 
     Console.WriteLine(string.Format(" Key: {0}, Value: {1}", item.Key, item.Value)); 
} 
3

è possibile utilizzare un Linq Select e string.join per ottenere il risultato che si desidera.

string.Join(Environment.NewLine, 
    elem.Attributes.ToObjectArray() 
     .Select(a => "Name=" + a.Name + ", Value=" + a.Value) 
) 
+1

'String.Format()' sarebbe una scelta migliore: '.Select (a => string.format (" Nome = {0}, Valore = {1} ", a.Nome, a.Valore))' – MarcinJuraszek

+0

elem.Attributes.ToObjectArray() .Select (a => "Name =" + a.Name + ", Value =" + a.Value); non fornire a.nome e a.Valore qui. Ho già provato questo, ma non è restituito a.Nome e a.Valore. –

2

Questa volontà ottieni tutti gli attributi dei figli dell'elemento Detail come affermi nella tua domanda.

XDocument x = XDocument.Parse("<Students> <student> <Detail Name=\"abc\" Class=\"1st Year\"> <add key=\"Main\" value=\"web\"/> <add key=\"Optional\" value=\"database\"/> </Detail> </student> </Students>"); 

var attributes = x.Descendants("Detail") 
        .Elements() 
        .Attributes() 
        .Select(d => new { Name = d.Name, Value = d.Value }).ToArray(); 

foreach (var attribute in attributes) 
{ 
    Console.WriteLine(string.Format("Name={0}, Value={1}", attribute.Name, attribute.Value)); 
} 
0

Se si dispone dei attributi in un object[] come hai scritto, che può essere deriso da

var Attributes = new object[]{ 
    new {Name="key", Value="Main"}, 
    new {Name="value", Value="web"} 
}; 

allora il problema è che avete tipi anonimi i cui nomi non possono essere estratto facilmente.

Date un'occhiata a questo codice (è possibile incollarlo nel metodo main() di una finestra di editor LINQPad per eseguirlo):

var linq=from a in Attributes 
let s = string.Join(",",a).TrimStart('{').TrimEnd('}').Split(',') 
select new 
{ 
    Value = s[0].Split('=')[1].Trim(), 
    Name = s[1].Split('=')[1].Trim() 
}; 
//linq.Dump(); 

Dal momento che non è possibile accedere al nome e le proprietà valore della variabile Attributi all'interno dell'oggetto [] perché il compilatore li nasconde da te, il trucco è qui per utilizzare il metodo Join (",", a) per aggirare questa limitazione.

Tutto quello che dovete fare dopo è di tagliare e dividere la stringa risultante e, infine, creare un nuovo oggetto con Valore e Nome proprietà. Si può provare se si decommenta il file linq.Dump(); riga in LinqPad - restituisce ciò che si desidera ed è inoltre interrogabile dalle istruzioni Linq.

Problemi correlati