Laden...

Einfache XML-Pfad Adressierung

Erstellt von perlfred vor einem Monat Letzter Beitrag vor einem Monat 209 Views
P
perlfred Themenstarter:in
261 Beiträge seit 2010
vor einem Monat
Einfache XML-Pfad Adressierung

Hallo!

Ich habe etwas ganz triviales ... , ich möchte den Wert eines Knoten in einer XML-Datei abfragen.

Die XML-Struktur ist gut Strukturiert aber umfangreich. Ich möchte die relevanten Knoten deshalb mit einem absoluten Pfad ansprechen und nicht durch Iterieren mich durch die Baumstruktur kämpfen.

Die Abfrage des Knotenpunktes Registriernummer:

doc = new XmlDocument();                                                    // XML-Dokument instanzieren
doc.Load(Path.Combine(EADatenVerzeichnis, dEintrag.EADatei_Name));          // XML-Daten laden
XmlElement root = doc.DocumentElement;                                      // Root-Knoten initalisieren
                
string RegNr = root.SelectSingleNode("/Energieausweis-Daten/Registriernummer").Value;

ergibt immer null!

Der Root-Knoten (root) enthält alle Eigenschaften wie man der Schnellansicht des Debuggers (Anhang) entnehmen kann, aber die Pfad-Angabe scheint noch falsch zu sein, was ich nicht nachvollziehen kann.

Die XML-Datei:

<?xml version="1.0"?>
<GEG-Energieausweis xmlns="https://energieausweis.dibt.de/schema/Kontrollsystem-GEG-2024_V1_0.xsd">
  <Gebaeudebezogene-Daten>
    <Gebaeudeadresse-Strasse-Nr>Rosenweg 18-44</Gebaeudeadresse-Strasse-Nr>
         ...
    </Gebaeudebezogene-Daten>
  <Energieausweis-Daten Gesetzesgrundlage="GEG-2024" Rechtsstand="2024-04-04" Rechtsstand-Grund="Ausweisausstellung (bei Verbrauchsausweisen und alle anderen Fälle)">
    <Registriernummer>SN-2024-005026180</Registriernummer>
    ...
16.864 Beiträge seit 2008
vor einem Monat

Zitat von perlfred

ergibt immer null!

Naja, Du verwendest eine XML Implementierung, die auf XPath basiert - dann musst halt auch das machen, wie XPath funktioniert.

Du darfst die Klasse XmlElement nicht verwenden wie XElement. Beide Klassen existieren, beide haben ihre Vor- und Nachteile - aber beide Klassen funktionieren nicht identisch (und das ist gut so).

Der Root-Knoten (root) enthält alle Eigenschaften wie man der Schnellansicht des Debuggers (Anhang) entnehmen kann, aber die Pfad-Angabe scheint noch falsch zu sein, was ich nicht nachvollziehen kann.

Du hast eine XML Namespace (zeigt auf ein Schema), ergo muss Dein Zugriff auch über das Namepsace erfolgen. Auch stimmt einfach der XPath nicht.

Siehe direkt das Sample in der Docs von SelectSingleNode, was Du hier verwendest.

P
perlfred Themenstarter:in
261 Beiträge seit 2010
vor einem Monat

Hallo Abt!

Danke für die schnelle Antwort (mit der ich noch nicht zurecht komme).

Die im NameSpace angegebene Schema-Datei (xsd) habe ich nicht.

In dem MS-Beispiel wird doch für das root-Element auch die Klasse XmlElement benutzt. Was sollte ich denn alternativ verwenden?

Ich sehe mir den Teil mit dem NameSpace-Manager noch einmal an, ich dachte ohne die Angabe eines NameSpaces geht es auch.

Danke für die Hinweise!

16.864 Beiträge seit 2008
vor einem Monat

Zitat von perlfred

Die im NameSpace angegebene Schema-Datei (xsd) habe ich nicht.

Hat auch niemand gesagt, dass Du das brauchst. 😃 Aber Du brauchst den Namespace. Hört sich danach an, dass Du nicht weißt, was der Namespace macht: dann les es Dir durch.

In dem MS-Beispiel wird doch für das root-Element auch die Klasse XmlElement benutzt. Was sollte ich denn alternativ verwenden?

Ja wird es, aber es wird zusammen mit dem Namespace verwendet, was Du nicht machst. Es ist halt ein default Namespace, kann also sein, dass kein explizites Verwenden notwendig ist (weiß ich nicht auswendig); aber der Zugriff ist definitiv so nich korrekt.

P
perlfred Themenstarter:in
261 Beiträge seit 2010
vor einem Monat

Hallo Abt!

Ok, ich beschäftige mich erst einmal damit...

16.864 Beiträge seit 2008
vor einem Monat
XmlDocument doc = new();
XmlNamespaceManager ns = new(doc.NameTable);
ns.AddNamespace("ns", "https://energieausweis.dibt.de/schema/Kontrollsystem-GEG-2024_V1_0.xsd");

doc.Load("a.XML");

XmlNode node = doc.SelectSingleNode("//ns:GEG-Energieausweis/ns:Energieausweis-Daten/ns:Registriernummer", ns);


Console.WriteLine(node.InnerText);

Ist im Endeffekt der Code aus dem Beispiel der Docs - funktioniert einwandfrei.

Fazit: immer besser mal kurz nen Blick in die Docs zu werfen und anzuschauen, wie das Zeug funktioniert, das man verwendet 😉

P
perlfred Themenstarter:in
261 Beiträge seit 2010
vor einem Monat

Hallo Abt!

Kann Microsoft nicht so ein einfaches, intuitives Beispiel wie deins, bei der Beschreibung von SelectSingleNode verwenden? Nein, da muss schon wieder gefiltert werden und eine Abfrage über untergeordnete Knoten (descendand) dargestellt werden. Als zweites Beispiel vielleicht ganz interessant, aber um das Prinzip zu verstehen nicht gerade hilfreich. (Anmerkung: Ich hatte mir die Dokumentation schon angesehen, aber nicht verstanden.)

Der Fehler bei mir war also: Das ich einen NameSpace Alias definieren muss und diesen im Pfad (bei jedem Knoten) voranstellen muss.

Jetzt habe ich deinen Hinweis:

aber der Zugriff ist definitiv so nich korrekt

verstanden.

doc = new XmlDocument();                                                    // XML-Dokument instanzieren
doc.Load(Path.Combine(EADatenVerzeichnis, dEintrag.EADatei_Name));          // XML-Daten laden

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);         // NameSpace Manager initalisieren
nsmgr.AddNamespace("dibt", "https://energieausweis.dibt.de/schema/Kontrollsystem-GEG-2024_V1_0.xsd");   // Spezifischen Namespace als/mit Alias dem NameSpace Manager hinzufügen
               
XmlElement root = doc.DocumentElement;                                      // Root-Knoten initalisieren

string RegNr = doc.SelectSingleNode("//dibt:GEG-Energieausweis/dibt:Energieausweis-Daten/dibt:Registriernummer", nsmgr).InnerText;  // Über voll qualifizierten Pfad (NS-Alias:Knoten-Name) auf den gewünschten Knoten zugreifen

Wieder vielen Dank für deine Hilfe!!!

16.864 Beiträge seit 2008
vor einem Monat

Zitat von perlfred

Kann Microsoft nicht so ein einfaches, intuitives Beispiel wie deins, bei der Beschreibung von SelectSingleNode verwenden? Nein, da muss schon wieder gefiltert werden und eine Abfrage über untergeordnete Knoten (descendand) dargestellt werden. Als zweites Beispiel vielleicht ganz interessant, aber um das Prinzip zu verstehen nicht gerade hilfreich. (Anmerkung: Ich hatte mir die Dokumentation schon angesehen, aber nicht verstanden.)

Das ist halt die Doku zur Methode; keine Dokumentation zur grundlegenden Funktionalität von XPath.

Wenn Du in die Anleitung eines Autos schaust, und schaust wie man den Sitz verstellt, dann steht da auch nicht dran wie man das Auto aufschließt, um sich auf den Sitz zu setzen - da wird schon von ausgegangen, dass Du schon drin sitzt 😉