Laden...

Wert in XML-Datei suchen und auslesen

Erstellt von Sasa vor 17 Jahren Letzter Beitrag vor 17 Jahren 4.646 Views
S
Sasa Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren
Wert in XML-Datei suchen und auslesen

Hallo,

es geht um eine XML-Datei, die mehrere Einträge, wie diesen hier enthält:

<Airport country='United States' state='' city='San Francisco' name='San Francisco Intl.' lat='26.7887477840029' lon='14.2414503521609' alt='479.9583125' ident='USS19'>

Ich möchte aus der XML-Datei den Wert auslesen, der hinter ident steht (also in diesem Fall USS19) auslesen.
Allerdings mit einem Knackpunkt: In der Datei stehen mehrere idents, und ich möchte nur den letzten, ganz unten in der Datei stehenden, ausgelesen haben.

Irgendwelche Ideen? Für ein Codebeispiel wäre ich natürlich extrem dankbar! 🙂

Grüsse
Sascha

2.082 Beiträge seit 2005
vor 17 Jahren

Hallo Sasa,

schau dir mal XmlDocument, XmlAttribute und dazu die Value an.

kleiner Tipp: SelectSingleNode bzw. SelectNodes

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

3.003 Beiträge seit 2006
vor 17 Jahren

Einfacher:


System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.load("myXml.xml");
string lastIdent = doc.FirstChild.LastChild.Attributes["ident"];

Kannst du machen, wenn du die Struktur genau kennst (falls da noch mehr Ebenen sind, einfach weiter hinunter hangeln...).

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

S
Sasa Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Vielen Dank erst einmal! Das hilft mir schon mal weiter. 🙂
Allerdings bekomme ich mit LaTinos Codebeispiel eine Fehlermeldung zu dritten Zeile: "Implizite Konvertierung des Typs 'System.Xml.XmlAttribute' zu 'string' nicht möglich".

Sorry, dass ich euch mit solchen Fragen zu Basis-Wissen nerve. Ich hätte wohl am Anfang meines C#-Buches anfangen sollen und nicht in der Mitte. Momentan muss ich aber sehr schnell fertig werden und freue mich über jede weitere Hilfe umso mehr. X(

Grüsse
Sascha

C
65 Beiträge seit 2006
vor 17 Jahren

string lastIdent = doc.FirstChild.LastChild.Attributes["ident"];
wird zu =>
string lastIdent = doc.FirstChild.LastChild.Attributes["ident"].toString();

3.003 Beiträge seit 2006
vor 17 Jahren

Nicht ganz.


string lastIdent = doc.FirstChild.LastChild.Attributes["ident"].Value;

Sorry. Mir fehlt hier noch IntelliSense im Forum 😄.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

C
65 Beiträge seit 2006
vor 17 Jahren

hm stimmt vergessen das der inhalt gesucht war 😜
jo intellisense wär ganz nützlich 😁
myc#3.de abwarten ^^

1.373 Beiträge seit 2004
vor 17 Jahren

Man könnte hier auch gut XPath einsetzen:


XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
XPathNavigator node = nav.SelectSingleNode("//Airport[position()=last()]/@ident");
string lastIdent = node.Value;

Grüße,
Andre

P.S.:
Wenn das ident-Attribute optional ist, musst du das hier verwenden:


"//Airport[@ident][position()=last()]/@ident"

Wenn du alternativ das letzte ident-Attribut suchst (egal welches Element), dann ginge:


"//*[@ident][position()=last()]/@ident"

als XPath.

S
Sasa Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Arg! So viele Möglichkeiten! Jungs, ihr treibt mich noch zum Wahnsinn... 😁
Sieht so aus, als wenn ich mich noch ein paar Monate hinter die Bücher setzen muss, denn über die MSDN werde ich zu den ganzen ChildForms überhaupt nicht schlau (sind die Texte da mit einem Software-Translator übersetzt worden?).

Die Struktur des XML-Dokuments sieht so aus:

Weil Airport ja weder das FirstChild, noch das LastChild ist (soweit ich das verstanden habe), habe ich es mal mit VizOne's Version versucht. Allerdings bekomme ich hier haufenweise Fehlermeldungen, dass XPath, XPathNavigator und XPathNavigator nicht gefunden wurden. Ein Include für System.Xml besteht aber. ?(

Grüsse
Sascha

C
65 Beiträge seit 2006
vor 17 Jahren
  1. System.Xml.Xpath ??
    2.<Airport> kann lastchild sein (im <FSData> Tag!)
S
Sasa Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren
  1. System.Xml.Xpath ??

Stimmt. Hatte ich auch schon probiert, bekomme dann aber weitere Fehlermeldungen. Hier noch der aktuelle Code:

			System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument();
			doc.Load("AF2_CoastGuard.xml");
			System.Xml.XPath.XPathNavigator nav = doc.CreateNavigator();
			System.Xml.XPath.XPathNavigator node = nav.SelectSingleNode("//Airport[position()=last()]/@ident");
			string lastIdent = node.Value; 

Auf 'System.Xml.XPath.XPathDocument.XPathDocument()' ist der Zugriff aufgrund der Sicherheitsebene nicht möglich
Auf 'System.Xml.XPath.XPathDocument.Load(System.Xml.XmlReader)' ist der Zugriff aufgrund der Sicherheitsebene nicht möglich
'System.Xml.XPath.XPathNavigator' enthält keine Definition für 'SelectSingleNode'

Grüsse
Sascha

1.373 Beiträge seit 2004
vor 17 Jahren

Benutzt du .NET 2? Davon war ich nämlich ausgegangen.

Grüße,
Andre

C
65 Beiträge seit 2006
vor 17 Jahren

Folgender Code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace sasaandxml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument input = new XmlDocument();
            input.Load("C:/temp/doc.xml");
            string inhalt = input.SelectSingleNode("//Airport[position()=last()]/@ident").Value; //endet erst hier!
   //vorsicht! hier falsch auskommentiert wg codetag!
            Console.WriteLine(inhalt);
            Console.Read();
        }
    }
}


generiert bei folgender xml:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<FSData>
<Airport country='United States' state='' city='San Francisco' name='San Francisco Intl.' lat='26.7887477840029' lon='14.2414503521609' alt='479.9583125' ident='USS19erster'>
</Airport>
<Airport country='United States' state='' city='San Francisco' name='San Francisco Intl.' lat='26.7887477840029' lon='14.2414503521609' alt='479.9583125' ident='USS19zwoter'>
<InnerTag>blub</InnerTag>
</Airport>
<Airport country='United States' state='' city='San Francisco' name='San Francisco Intl.' lat='26.7887477840029' lon='14.2414503521609' alt='479.9583125' ident='USS19letzter'>
<InnerTag>blub</InnerTag>
</Airport>
</FSData>
</root>

folgenden output:
USS19letzter
ergo: funktioniert
arbeite ohne xpathnavigator, nur aufm DOM und nutze xpath

p.s. die xml hab ich zum testen selbst zammegeschusstert, bin mir aber fast sicher das es direkt auf deine xml anwendbar sein wird 😉
ansonsten dürfte dir das als hilfe genügen 🤔 8)

1.373 Beiträge seit 2004
vor 17 Jahren

Ja, für .NET 1.1 gehts auch so. Wie gesagt, ich bin von .NET 2 ausgegangen und da ist das XPathDocument vorzuziehen, weil es viel "leichter" und schneller ist.

Grüße,
Andre

C
65 Beiträge seit 2006
vor 17 Jahren

hm
schneller nun gut kann gut sein da wohl nicht das ganze dokument geladen wird sondern nur durchnavigiert wird ABER:

ist das element ganz unten, das dokument würde fast komplett geladen werden!

in meinem beispiel wird das dokument 1x gelesen 1x bearbeitet (durchsucht nach der node) (wobei ich mir nit sicher bin wie das xpathdokument erzeugt wird o.ä.)
ich brauche 3 zeilen code er min. 5, also was "leichter" ist sei dahingestellt 🤔
ausserdem funktioniert mein beispiel, das ist wohl das wichtigste (vorallem bei so einer trivialen aufgabe wie suche element x mit attribut y aus xy.xml)
ich persönlich bevorzuge das xmldocument...
p.s. trotz .net 2.0

1.373 Beiträge seit 2004
vor 17 Jahren

Mit "leichter" meinte ich den Speicherverbrauch. Ich kann gegen deine persönlichen Vorzüge nichts sagen, aber ich möchte doch jedem empfehlen, zum Suchen innerhalb größerer XML Dokumente und beim Transformieren mittels XSLT ein XPathDocument zu verwenden.

Grüße,
Andre

http://jdixon.dotnetdevelopersjournal.com/xpath_performance_in_net.htm
http://jira.public.thoughtworks.org/browse/CCNET-103
http://support.microsoft.com/default.aspx?scid=kb;en-us;325689
etc.

S
Sasa Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Danke euch allen. Hier jetzt der Code, mit dem es funktioniert:

			XmlDocument input2 = new XmlDocument();
			input2.Load("test.xml");
			string inhaltIdent = input2.SelectSingleNode("//Airport[position()=last()]/@ident").Value;

			inhaltIdent = inhaltIdent.Substring(2,3);
			float inhaltIdent2 = 0;
			inhaltIdent2=Convert.ToInt16(inhaltIdent)+1;
			string inhaltIdent3 = "";
			inhaltIdent3=Convert.ToString(inhaltIdent2);
			if (inhaltIdent3.Length < 2)
			{
				inhaltIdent3 = "00" + inhaltIdent3;
			}
			if (inhaltIdent3.Length < 3)
			{
				inhaltIdent3 = "0" + inhaltIdent3;
			}
476 Beiträge seit 2004
vor 17 Jahren
Verbesserungsvorschläge...

Hallo Sasa,
erst mal Glückwunsch zum funktionierenden Code. Allerdings möchte ich Dir noch ein paar Verbesserungsvorschläge unterbreiten...


			inhaltIdent = inhaltIdent.Substring(2,3);

Hat sich da ein Tippfehler eingeschlichen? Müsste doch 3,2 heissen... aber nuja, damit legst Du Dich fest wie groß der numerische Teil deines Ident ist, da Du aber weiter unten 1 addierst, könnte ja sein, dass dur irgendwann bei mehr Stellen bist (99 -> 100).


float inhaltIdent2 = 0;
inhaltIdent2=Convert.ToInt16(inhaltIdent)+1;
string inhaltIdent3 = "";
inhaltIdent3=Convert.ToString(inhaltIdent2);

Weshalb verwendest Du hier einen float (bzw. single). Das macht keinen Sinn. Du konvertierst deine Variable in einen Integer, was für eine Ganzzahl auch sinnvoll ist. Die Zuweisung funktioniert auch, da du eine Ganzzahl in eine Gleitkommazahl konvertieren kannst, aber ich würde mir so etwas abgewöhnen, bei komplexerem Code kann das schnell zu Fehlern führen.

Zu:


if (inhaltIdent3.Length < 2)
  {
    inhaltIdent3 = "00" + inhaltIdent3;
   }
if (inhaltIdent3.Length < 3)
  {
    inhaltIdent3 = "0" + inhaltIdent3;
}

würde ich zu folgendem Ersatz vorschlagen:


inhaltIdent3 = InhaltIdent3.PadLeft(3,'0');

-yellow

Selbst ein Weg von tausend Meilen beginnt mit einem Schritt (chinesisches Sprichwort).

Mein Blog: Yellow's Blog auf sqlgut.de