2 Stimmen

Laden von XML-Knoten mit wiederholten Namen mit Linq [C#]

Ich arbeite an einem Programm, das in der Lage, Objekt-Eigenschaften aus einer XML-Datei zu laden sein muss. Diese Eigenschaften sind konfigurierbar durch den Benutzer und XML macht Sinn für mich zu verwenden.

Nehmen Sie das folgende XML-Dokument.

<?xml version="1.0" encoding="utf-8" ?>

<udpcommands>

  <command name="requser">
    <cvar name="reqchallege" value="false" />
  </command>

  <command name="reqprocs">
    <cvar name="reqchallenge" value="false" />
  </command>

</udpcommands>

Ich muss in der Lage sein, Werte aus den oben genannten Variablen in Eigenschaften zu laden. Ich denke, Linq-zu-XML wäre gut für sie sein ( Ich suche nach Anwendungen für Linq, damit ich es lernen kann. ). Ich habe eine Linq-to-XML-Abfrage durchgeführt, um den richtigen "Befehl" auf der Grundlage des Namens auszuwählen, und ich habe gelesen MSDN um Hilfe zu bitten.

Der folgende Codeschnipsel wird in einen Konstruktor eingefügt, der den Parameter "string name" entgegennimmt, der das richtige XML identifiziert <command> zu ziehen.

Ich würde gerne eine Linq-Anweisung haben, um jede <cvar> aus dieser XML mit dem Namen des Abschnitts und speichert alles in einer IEnumerable. Oder ich suche vielleicht nach einer besseren Option. Ich bin wirklich für alles offen. Ich möchte nur Linq verwenden, damit ich es besser lernen kann.

    XElement doc = XElement.Load("udpcommands.xml");

    IEnumerable<XElement> a = from el in doc.Elements()
                              where el.FirstAttribute.Value == name
                              select el;

    foreach (var c in a)
    {
        Console.WriteLine(c);
    }

Der obige Codeschnipsel gibt folgendes auf der Konsole aus:

<command name="requser">
  <cvar name="reqchallege" value="false" />
</command>

2voto

Winston Smith Punkte 20909

Etwas in der Art sollte genügen:

var result = 
    doc.Elements("command")
    .Single( x => x.Attribute("name").Value == name)
    .Elements("cvar");

Dadurch erhalten Sie eine IEnumerable<XElement> wobei jeder XElement stellt eine cvar in dem angegebenen Befehl.

Beachten Sie, dass der Aufruf von Single einen Fehler verursacht, wenn der angegebene Befehl nicht existiert. Das Gleiche gilt, wenn das angegebene Attribut im Befehl nicht gefunden wird.

EDIT Wie in Ihren Kommentaren beschrieben, könnten Sie etwas in der Art machen:

// Result will be an XElement, 
// or null if the command with the specified attribute is not found
var result = 
    doc.Elements("command")
    // Note the extra condition below
    .SingleOrDefault( x => x.Attribute("name")!=null && x.Attribute("name").Value == name)

if(result!=null)
{
    // results.Elements() gives IEnumerable<XElement>
    foreach(var cvar in results.Elements("cvar"))
    {
        var cvarName = cvar.Attribute("name").Value;
        var cvarValue = Convert.ToBoolean( cvar.Attribute("value").Value );
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X