Autor Beitrag
Ivy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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 -.-

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 203
Erhaltene Danke: 18

Win > XP, Vista, 7; Android 2.1
C# > VS '08,'10; Delphi7
BeitragVerfasst: Do 07.10.10 09:27 
Ich benutze immer XDocument und XElement :o
damit ist das speicher von strings sehr einfach.

ausblenden C#-Quelltext
1:
2:
3:
XDocument xDoc = XDocument.Load(/*MyFilePath*/);
var xEle = xDoc.Root.AddElement(/*stuff*/);
//...
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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:

ausblenden 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);//wählt knoten

            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.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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:

ausblenden 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:

ausblenden 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: Di 12.10.10 14:52 
user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
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.

ausblenden 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();
        
        //Typ wählen
        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);
        //Speichern 
        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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Di 12.10.10 15:19 
Mach einfach eine Klasse welche die Benutzereinstellungen beinhaltet. Also laut deiner Xml eine Liste von Geräten:

ausblenden 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:

ausblenden C#-Quelltext
1:
2:
3:
    public abstract class Device
    {
    }


und implementierst dann die konkreten Devices IECBus und RS232:

ausblenden 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:
ausblenden volle Höhe 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:
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:
ausblenden 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.:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: 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 -.-

ausblenden C#-Quelltext
1:
 XmlNodeList xnList = doc.SelectNodes("/Setting/RS232Gerät/RS232");					
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228



BeitragVerfasst: Mi 20.10.10 08:25 
user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
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....