Autor Beitrag
ninJa_neon
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 26.06.10 18:47 
Hallo,

ich habe in c# ein xml-File geschrieben, dass die Daten eines Widerstandes speichert:

ausblenden XML-Daten
1:
2:
3:
4:
5:
<Widerstand>
    <ZAHL>47</ZAHL>
    <WERT>47R</WERT>
    <BEST>423203 -62</BEST>
  </Widerstand>


usw.

In meinem Programm gibt der User einen Wert ein, z.B. 50, dieser Wert soll dann mit allen Zahlen (<ZAHL>) verglichen werden. Wenn das Programm dann den passenden Widerstand mit dem nächsten Wert gefunden hat möchte ich <Wert> und <Best> in einer listview ausgeben. Habe gerade erst mit xml angefangen und hoffe, dass mir jemand helfen kann.

mfg

Moderiert von user profile iconChristian S.: XML-Tags hinzugefügt
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Sa 26.06.10 19:50 
Hallo und :welcome:,

für Xml gibt es ein sprachenunabhängige Abfragesprache namens XPath. Dies kannst du verwenden um deinen Entsprechenden Widerstand zu finden.

Die .NET Implementierung für Xml findest du als XmlDocument (alt) und XDocument (Linq). Verwende XDocument, das ist schneller und konfortabler.

Um eine Xml-Document damit einzulesen genügt:
ausblenden C#-Quelltext
1:
XDocument doc = XDocument.Load("deine.xml");					


Um ein Element anhand eines XPath-Ausdruck zu finden musst du den Namespace using System.Xml.XPath; einbinden. Dann gibt es einige Erweiterungsmethoden wie zum Beispiel: XPathSelectElement. Mit dieser kannst du mit einem XPath Ausdruck ein Element auswählen. XPath ist zu umfangreich dass ich es dir hier erklären möchte.
Deshalb verweise ich hier auf folgende Links:
de.wikipedia.org/wiki/XPath
de.selfhtml.org/xml/...lung/xpathsyntax.htm
www.w3schools.com/xpath/default.asp

Der Befehl könnte dann so aussehen:
ausblenden C#-Quelltext
1:
doc.XPathSelectElement("/Widerstand[ZAHL='47']");					


Viel Erfolg & Gruß,

Moderiert von user profile iconChristian S.: C#-Tag repariert
ninJa_neon Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: So 27.06.10 16:02 
Ich habe versucht das Problem mit folgendem Code zu lösen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
int wert = Convert.ToInt32(txtBox_R_Wert.Text);
            string strwert = Convert.ToString(wert);
            string listWert, listBest;

            var doc = new XPathDocument(@"F:\INFORMATIK\Csharp\PROJEKT_2010\XML\W6_MFR_0p1.xml");
            foreach (XPathNavigator navigator in doc.CreateNavigator().Select("/W6_Metallschichtwiderstand_0p1/Widerstand[@id=\"47\"]/child"))
            {
                listWert=Convert.ToString(navigator.InnerXml + navigator.GetAttribute("WERT"""));
                listBest=Convert.ToString(navigator.InnerXml + navigator.GetAttribute("BEST"""));
            }


...und die xml abgeändert:

ausblenden XML-Daten
1:
2:
3:
4:
<Widerstand id="47">
    <child WERT="47R"></child>
    <child BEST="423203 -62"></child>
  </Widerstand>


Irgendwie funktioniert das ganze aber nicht und ich habe keine Ahnung warum :(

danke erstmal für die Hilfe!

Moderiert von user profile iconChristian S.: C#-Tags hinzugefügt
Moderiert von user profile iconChristian S.: XML-Tags hinzugefügt
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 27.06.10 17:01 
Definiere bitte "funktioniert nicht".

Wenn XPath dir nicht sowieso schon bekannt ist, gibt es zumindest bei diesem Problem eigentlich keinen Grund, dich zusätzlich zur restlichen XElement-API damit beschäftigen zu müssen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
foreach (XElement widerstand in doc.Elements("Widerstand"))
  if ((int)widerstand.Element("ZAHL") == 42) {
    ...
    break;
  }

Ich beziehe mich auf deine erste XML-Struktur, denn "ZAHL" kann zwar ruhig ein Attribut werden, aber insgesamt war die eindeutig hübscher ;) .

_________________
>λ=
ninJa_neon Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: So 27.06.10 17:39 
Letzte Frage: Wie bekomme ich jetzt noch, dass er beim Widerstand auch die dazugehörige Bestellnummer und Wert ausgibt?

mfg
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 27.06.10 22:19 
Du beziehst dich auf meinen Vorschlag? Wenn ja, läuft das eigentlich ganz analog zum ZAHL-Element, das solltest du jetzt eigentlich übertragen können.

PS: Die fortgeschrittene Version, für die Zukunft ;) , wäre
ausblenden C#-Quelltext
1:
XElement widerstand = root.Elements("Widerstand").Single(e => (int)e.Element("ZAHL") == 42);					

Da ich normalerweise über XElement.Load gehe, soll root hier ein XElement sein. Deswegen ist auch mein Code im vorigen Beitrag nicht ganz korrekt: Ist doc ein XDocument, muss die Wurzel wie jedes andere Element explizit mit einbezogen werden (wie im XPath). Für die meisten Aufgaben ist XDocument aber eben gar nicht nötig.

_________________
>λ=
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: So 27.06.10 22:21 
Also das Foreach benötigt man nicht. Xpath bietet ja bereits die Möglichkeit (siehe mein Code oben).

Wenn du dein gewünschtes Element hast, kannst du über element.Element("ZAHL").Value bzw. element.Element("Wert").Value die entsprechenden werte auslesen. Ich berufe mich dabei auf den ersten Xml-Format. Das Zweite macht nämlich keinen Sinn. In der Regel sollte man auf Attribuite eher verzichten - ausgenommen solche wie ID natürlich.

Früher habe ich auch gerne Attribute genommen, weil es "einfacher" waren darauf zuzugreifen und sie eindeutig sind und es schöner aussieht und und und... allerdings habe ich die Erfahrung gemacht, das die Erweiterbarkeit darunter leidet. Der Zugriff ist nicht wirklich schwieriger und die lesbarkeit auch nicht.

Deshalb würde ich nehmen:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
<resistances>
   <resistance id="50">
      <value>50</value>
      <best>432432 - 52</best>
   <resistance>
</resistances>


Gruß