Autor |
Beitrag |
Ivy
      
Beiträge: 228
|
Verfasst: Do 07.10.10 09:07
hey
ich hab nochmal ne frage, wenn ich jetzt ein neues attribut hinzufüge möchte ich dass er diesen in die richtige "Abteilung" steckt. also kurz ich möchte einen neuen knoten an einer bestimmten stelle einfügen. wie geht das??
ich habs mit Select Nodes probiert geht aber i-wie nicht. also er trägt es weter immer ganz unten ein -.-
C#-Quelltext 1:
| XmlNodeList xnList = doc.SelectNodes("/Setting/RS232Gerät/RS232"); |
Zuletzt bearbeitet von Ivy am Do 21.10.10 09:23, insgesamt 5-mal bearbeitet
|
|
Necaremus
      
Beiträge: 203
Erhaltene Danke: 18
Win > XP, Vista, 7; Android 2.1
C# > VS '08,'10; Delphi7
|
Verfasst: Do 07.10.10 09:27
Ich benutze immer XDocument und XElement
damit ist das speicher von strings sehr einfach.
C#-Quelltext 1: 2: 3:
| XDocument xDoc = XDocument.Load(); var xEle = xDoc.Root.AddElement(); |
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Do 07.10.10 10:17
Hallo,
wenn du es nur abspeichern willst dann ist der DOM Ansatz XDocument sicherlich oversize und der XMLWriter reicht völlig aus. Willst du die Daten aber noch manipulieren rate ich dir auch zu XDocument.
Gruß
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Fr 08.10.10 10:46
okay danke habs mit dem XML Text writer gemacht.
hab ne neue frage aber dafür^^
ich habe eine XML Datei die wird standartmäßig immer beim Programmstart angelegt. In ihr sollen benutzereingaben gespeichert werden von der oberfläche. Nun meine frage, wie kann ich auf einen bestimmten pfad zugreifen un deren werte ändern.
XML-Daten 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| <Setting> <IECBus> <IECGerät> <Name>xyz</Name> <Adresse>17</Adresse> </IECGerät> <IECGerät> <Name>abc</Name> <Adresse>10</Adresse> </IECGerät> <RS232> <Port>COM1</Port> <Nummer>1</Nummer> </RS232> <RS232> <Port>COM7</Port> <Nummer>7</Nummer> </RS232> </IECBus> </Setting> |
wenn der benutzer also jetzt nur im Baum RS232 den port geändert hat soll er da hinspringen un es ändern und speichern.
vielen dank schonmal...
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Fr 08.10.10 11:05
Sind das Settings für die Anwendung? Sieht so aus.
Dafür gibt es von VS ein Vorgehensweise die Einstellungen als Objekt kapsel und als Xml abspeichert. Ich denke das ist das was du brauchst. Schaus dir mal bei MSDN an.
Gruß
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Fr 08.10.10 11:12
ja das sind einstellungen...
hm ja aber das programm muss ja i-wie in den richtigen pfad der xml datei springen un dort dann die daten abändern. also der benutzer sagt, so ich will jetz den port im baum RS232 ändern springt er dort hinein un ändert das was der Benutzer eingibt.
genau das ist was ich gesucht habe: www.codeproject.com/KB/cpp/myXPath.aspx
Nur eine frage jetzt, ich möchte meine datei aktualisieren, dafür ist folgender code zuständig:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| string str = comboBox2.Text; if (str == "") return;
alterName = str; expr = nav.Compile("/Setting/IECBus/IECGerät[@Typ='" + str + "']"); iterator = nav.Select(expr); if (iterator.MoveNext()) { XPathNavigator nav2 = iterator.Current.Clone(); nav2.MoveToFirstChild();
nav2.MoveToNext(); txtName.Text = nav2.Value; nav2.MoveToNext(); txtAdresse.Text = nav2.Value; } |
nur jetz bleibt er beim Pfad hängen un bringt diesen fehler:
Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
XML-Daten 1: 2: 3: 4: 5: 6:
| <Setting> <IECBus> <IECGerät> <Typ>IEC</Typ> <Name>NI</Name> <Adresse>17</Adresse> |
der pfad ist meiner meinung nach richtig ^^ mehr hab ich nicht abgeändert
weiß jemand wieso?
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Di 12.10.10 10:47
also das problem hab ich jetzt besieigt. Jetzt die nächste frage^^ ich möchte meine xml datei jetzt doch etwas anders gesatlten, nämlich dass die werte "variablen" (weiß nicht wie man das in xml nennt) speichert. in etwa so:
XML-Daten 1: 2:
| <IECGerät Name="ABC" Adresse="123"> </IECGerät> |
ja schön un gut, hab ich mir gedacht mach ich das einfach in C# so:
C#-Quelltext 1: 2: 3:
| XmlDocumentFragment docFrag = doc.CreateDocumentFragment(); docFrag.InnerXml = "<IECGerät Name=\"" + txtName.Text + "Adresse=\"" + txtAdresse.Text +"\">" + "</IECGerät>"; |
es kommt aber diese exception:
Ein Name darf nicht mit dem Zeichen '1', hexadezimaler Wert 0x31, beginnen. Zeile 1, Position 29.
hat jemand nen rat für mich warum???
EDIT:
C#-Quelltext 1: 2: 3:
| XmlDocumentFragment docFrag = doc.CreateDocumentFragment(); docFrag.InnerXml = "<IECGerät Name=\"" + txtName.Text + "\" Adresse=\"" + txtAdresse.Text + "\">" + "</IECGerät>"; |
so gehts jetzt, aber er überschreibt jedes mal den einen baum un legt nicht immer einen neuen an.
gruß ivy
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Di 12.10.10 11:24
Hi,
mach einfach eine Klasse mit den benötigen Eigenschaften. Mit dem XmlSerializer kannst du diese dann bequem in Xml umwandeln.
Gruß
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Di 12.10.10 14:52
danielf hat folgendes geschrieben : | Hi,
mach einfach eine Klasse mit den benötigen Eigenschaften. Mit dem XmlSerializer kannst du diese dann bequem in Xml umwandeln.
Gruß |
aha, versteh ich jetzt nicht so ganz was mir das bringen soll.
bin jetzt dabei die gespeicherten daten wieder aufzurufen un ändern zu können.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| try { XmlTextReader reader = new XmlTextReader(FILE_NAME); XmlDocument doc = new XmlDocument(); doc.Load(reader); reader.Close(); XmlNode oldCd; XmlElement root = doc.DocumentElement; oldCd = root.SelectSingleNode("Setting/IECBus/IECGerät[Typ='" + alterName + "']");
XmlElement newCd = doc.CreateElement("IECGerät"); newCd.SetAttribute("Name",txtName.Text + "Adresse", txtAdresse.Text);
root.ReplaceChild(newCd, oldCd); doc.Save(FILE_NAME); this.DialogResult = DialogResult.OK; } catch (Exception ex) { MessageBox.Show("Exception: {0}", ex.ToString()); this.DialogResult = DialogResult.Cancel; } |
dafür ist ja dieser teil verantwortlich. Es kommt aber ein fehler "der OBjektverweis wurde nicht auf eine objektinstanz festgelegt"
hab kp was das bedeutet^^
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Di 12.10.10 15:19
Mach einfach eine Klasse welche die Benutzereinstellungen beinhaltet. Also laut deiner Xml eine Liste von Geräten:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| public class Settings { public List<Device> Devices { get; set; }
public Settings() { Devices = new List<Device>(); } } |
Ein Device definierst du als abstrakte Oberklasse:
C#-Quelltext 1: 2: 3:
| public abstract class Device { } |
und implementierst dann die konkreten Devices IECBus und RS232:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public class RS232Device : Device { public string Port { get; set; }
public int PortNumber { get; set; } }
public class IECDevice : Device { public string Name { get; set; }
public string Adresse { get; set; } } |
So nun hast du deine Einstellungen als Objekte definiert.
Um diese nun zu serialisieren (als Xml String abzuspeichern) kannst du den XmlSerializer verwenden (siehe Beitrag oben).
Im Code könnte das dann so aussehen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| static void Main(string[] args) { Settings settings = new Settings();
settings.Devices.Add(new IECDevice { Adresse = "17", Name = "xyz" });
settings.Devices.Add(new IECDevice { Adresse = "10", Name = "abc" });
settings.Devices.Add(new RS232Device { Port = "COM1", PortNumber = 1 });
settings.Devices.Add(new RS232Device { Port = "COM7", PortNumber = 7 });
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
serializer.Serialize(File.OpenWrite(@"C:\settings.xml"), settings); } |
Da Device abstrakt ist, muss du dem XmlSerializer noch die Möglichen konkreten Objekte, mit XmlInclude bekannt machen:
C#-Quelltext 1: 2: 3: 4: 5:
| [XmlInclude(typeof(IECDevice))] [XmlInclude(typeof(RS232Device))] public abstract class Device { } |
Um die Elementnamen der Nodes/Element zu ändern muss du Attribute verwenden, z.B.:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| public class RS232Device : Device { [XmlElement(ElementName = "Port")] public string Port { get; set; }
[XmlElement(ElementName = "Nummer")] public int PortNumber { get; set; } } |
Änderungen, Erweiterungen und Verwendung kannst du nun über die Objekte machen.
Gruß
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Di 12.10.10 15:24
aha, also du würdest es ganz anders angehen als ich bis her, angelehnt an das beispiel, gemacht hab?!
weil dann müsst ich jetzt wieder alles umwerfen^^
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Di 12.10.10 15:40
Naja.. was heißt umwerfen... es hatte so ja noch nicht funktioniert.. und das "Umstellen" ist ja "kein" Aufwand und du hast dann eine Lösung die sehr schön erweiterbar und einsetzbar ist. Rate ich dir also auf jeden Fall.
Gruß
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Di 19.10.10 10:11
ich hab nochmal ne frage, wenn ich jetzt ein neues attribut hinzufüge möchte ich dass er diesen in die richtige "Abteilung" steckt. also kurz ich möchte einen neuen knoten an einer bestimmten stelle einfügen. wie geht das??
ich habs mit Select Nodes probiert geht aber i-wie nicht. also er trägt es weter immer ganz unten ein -.-
C#-Quelltext 1:
| XmlNodeList xnList = doc.SelectNodes("/Setting/RS232Gerät/RS232"); |
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Di 19.10.10 21:05
Bei einem Xml gibt es keine Reihenfolge - das ist so definiert. Deshalb solltest du dich nicht auf sowas verlassen.
|
|
Ivy 
      
Beiträge: 228
|
Verfasst: Mi 20.10.10 08:25
danielf hat folgendes geschrieben : | Bei einem Xml gibt es keine Reihenfolge - das ist so definiert. Deshalb solltest du dich nicht auf sowas verlassen. |
auf was verlassen??
aber ich hab zwei verschiedene bäume un der bentuzer kann zwei verschiedene knoten einfügen einmal IECGerät, das soll in IECBUS einsortiert werden un einmal RS232 das soll in den knoten RS232Gerät einsortiert werden....
|
|