Xml in C#
-
Hallo,
Ich habe da einer Frage zu XML in C#
Unzwar möchte ich mein Programm so Dynamisch halten das ich "später" nach dem release nur noch in der xml Datei etwas veräendern bzw erstellen muss und das im Quellcode umgesetzt wird.
zB:
möchte ich einen Balken peer GDI darstellen und möchte dazu nur:
<Balkendiagram>
<posX>50</posX>
<posY>60</posY>
<width>180</width>
<height>16</height>
<!-- Colors -->
<colorMSB>255</colorMSB>
<colorR>255</colorR>
<colorG>255</colorG>
<colorB>255</colorB>in die XML eingeben und der Balken wird umgesetzt.
-Funktioniert das mit XML - C#?
-gibts dazu Tutorials oder gute Seiten wo ich gucken kann?
-
Wenn ich dich jetzt richtig verstanden habe, liegt das Problem mehr in der Arbeit mit XML Dateien ...
eine Möglichkeit wäre das in C# entahltenem XmlDocument
Attribute eines XML-Dokumentes mit C# auslesen
(ist jetzt schon ein weiterführendes Beispiel, aber an sich erklärt sich das schon von alleine und wenn nicht hilf die MSDN sehr gut weiter)Ist aus meiner Sicht die einfachste Möglichkeit an Daten aus einer XML-Datei zu kommen.
MfG Tim
-
Hallo,
erstmal, ja.. das funktioniert mit XML.
Ein Beispiel kann ich dir leider zur zeit nicht anbieten, aber im Endeffekt hast du dir die Lösung schon selbst geschrieben.
Nimm dir eine Basisklasse:[Serializable] public abstract class Shape : ISerializable { public abstract void Draw(System.Drawing.Graphics g); public abstract void GetObjectData(SerializationInfo info, StreamingContext context); }
und packe diese in einer Liste zu deiner Grafik/Control:
public class Graph : System.Windows.Forms.Control { //... Control-Logik etc. protected override OnPaint(.....) { base.OnPaint(....); foreach(Shape shape in shapes) { shape.Draw(....); } } private List<Shape> shapes; }
Eigentlich wars das schon... Musst nun nur noch die Draw- und GetObjectData-Methode überschreiben, zum start und ende des Programms jeweils de/serialisieren, und die Shapes zur internen Liste hinzufügen.
-
also mein Problem des Arbeiten mit den xml ist nicht das Ding. Ich Konfiguire momentan mein Projekt über eine xml nur ist das "halb"Dynamisch. Ich muss trotzdem jedesmal noch den Quellcode ändern und dazu die xml Datei.
mal ein Beispiel mehr:
// level 1... string levelOne = "Balkendiagram1/"; string colorpath1 = "left_xml/Balkendiagram1/"; xml_reader xml1 = new xml_reader(); int IposX1 = xml1.check_xml_int(posX, root, levelOne); int IposY1 = xml1.check_xml_int(posY, root, levelOne); int Iwidth1 = xml1.check_xml_int(width, root, levelOne); int Iheight1 = xml1.check_xml_int(height, root, levelOne); int ColorMSB1 = xml1.xml_Color(colorMSB, colorpath1); //Most Significant Byte! (255) int ColorR1 = xml1.xml_Color(colorR, colorpath1); //Red int ColorG1 = xml1.xml_Color(colorG, colorpath1); //Green int ColorB1 = xml1.xml_Color(colorB, colorpath1); //Blue Graphics g1 = pe.Graphics; //g1 wird Graphic Rectangle rect1 = new Rectangle(IposX1, IposY1, Iwidth1, Iheight1); //rect1 bekommt Werte eines Rechtecks(x,y, länge,höhe) LinearGradientBrush lBrush1 = new LinearGradientBrush(rect1, Color.FromArgb(ColorMSB1, ColorR1, ColorG1, ColorB1), Color.FromArgb(ColorMSB1, ColorR1, ColorG1, ColorB1), LinearGradientMode.BackwardDiagonal); g1.FillRectangle(lBrush1, rect1); //Füllen des Rechteckes!
und dazu die xml:
<Balkendiagram1> <!-- IST --> <posX>50</posX> <posY>60</posY> <width>180</width> <height>16</height> <!-- Colors --> <colorMSB>255</colorMSB> <colorR>255</colorR> <colorG>255</colorG> <colorB>255</colorB> </Balkendiagram1>
Also ich denke ihr habt schon verstanden das eigentlich wenn ich in die xml etwas schreibe der teil der .cs Datei selbst "generiert" "erstellt" "erzeugt" oder sonst was wird ^^ ...
(Muss dazu sagen das es mein erstes Projekt in C# ist)
-
Aso noch mein eigens geschriebener xml_reader:
public class xml_reader { public int check_xml_int(string check, string root, string levelOne) { int checked_value = 0; string temp; string myXml = @"C:\Dokumente und Einstellungen\azubi-it\Eigene Dateien\Visual Studio 2005\Projects\mask\mask\mask_konfig.xml"; XmlDocument doc = new XmlDocument(); doc.Load(myXml); XmlNodeList xnl = doc.SelectNodes("/"); XmlNode xnValue = doc.SelectSingleNode(root + levelOne + check); temp = xnValue.InnerText; checked_value = Convert.ToInt32(temp); temp = ""; return checked_value; }
-
Du serialisierst viel zu kompliziert...
les dir mal das Beispiel durch http://msdn.microsoft.com/de-de/library/system.runtime.serialization.iserializable.aspx
-
najo - serialisieren ist auch nicht recht sicher
wenn es ein node nicht gibt oder dergleichen kanns beim serialisieren knallen
ich wuerd sagen das man eher mit unbekannten arbeiten sollten
GetElementsByTagName und dann drueber iterieren - dann kanns in der structur auch tiefer sein usw
wir arbeiten auf arbeit auch oefters mit xml - das darin bau relevante sachen stehen
da liest bzw sucht man entsprechend nach gewissen nodes - wenn die nicht da sind kommt ein default oder man denkt sich was anderes aus
serialisieren denk ich ist noch viel zu statisch
-
So wie Mr. Evil es beschrieben hat ist glaube ich der Ansatz den ich verfolgen muss bzw sollte.
naja einen kleinen Ablauf hab ich aus deiner Beschreibung rauslesen können.
-
Vielleicht ne doofe Frage aber:
wenn ich mir mit
XmlNodeList elemList = root.GetElementsByTagName("Mainheading");
in elemList alles in <Mainheading> stehende Speicher wie kann ich dann mit elemList weiter arbeiten so das ich auch auf die unterstrukturen einzeln zugreifen kann den bezug aber zu Mainheading wahre?
<Mainheading>
<value>Test1</value>
<fontsize>16</fontsize>
<fontstyle>Arial</fontstyle>
</Mainheading>Im späteren Verlauf des Programmes kann ich ja nicht einfach meine komplette <value> durchlaufen wenn ich zB. nur value von Headings haben möchte ... darum gehts.
-
hi
ganz einfach
ausgehend davon:
<Item> <value>Test1</value> <fontsize>16</fontsize> <fontstyle>Arial</fontstyle> </Item> <Item> <value>Test2</value> <fontsize>17</fontsize> <fontstyle>MS Sans Serif</fontstyle> </Item>
XmlNodeList elemList = root.GetElementsByTagName("Item"); foreach(XmlElement itemElement in elemList) { string value = GetChildInnerText(itemElement, "value", "Test"); string fontSize = GetChildInnerText(itemElement, "fontsize", "12"); string fontStyle = GetChildInnerText(itemElement, "fontstyle", "Verdana"); } string GetChildInnerText(XmlElement parent, string nodeName, string default) { XmlNodeList node = parent.GetElementsByTagName(nodeName); if (node.Length() < 1) return default; return node[0].InnerText; }
beachte aber das GetElementsByTagName auch unterobjekte einbezieht - also das "Item" zb kann auch tiefer liegen, dann wirds mit genommen
bei dein Mainheading hast du evtl nur eines - aber das laeuft dann aehnlich
der vorteil wie zu sehen ist - das element muss nicht existieren damits laeuft - zusaetzliche oder fehlende nodes sind kein problem , das waeren sie aber beim serialisierenes gibt natuerlich sehr viele moeglichkeiten die xml zu lesen
auf jeden fall solltest du davon aus gehen das ein node evtl nicht existiert - oder sich die struktur aendert
der obige code geht zb weiterhin _ohne aenderung_ wenn man die xml zb so aussehen laesst:<Items> <Item> <value>Test1</value> <fontsize>16</fontsize> <fontstyle>Arial</fontstyle> </Item> <Item> <value>Test2</value> <fontsize>17</fontsize> <fontstyle>MS Sans Serif</fontstyle> </Item> </Items>
oder
<Item> <values> <value>Test1</value> <value>Test2</value> </values> <fontsize>16</fontsize> <fontstyle>Arial</fontstyle> </Item> <Item> <content> <value>Test2</value> <fontsize>17</fontsize> <fontstyle>MS Sans Serif</fontstyle> </content> </Item>
-
Das läuft Prima danke dafür erstmal.
Jetzt muss ich sehen wie ich das so hinbekomme das sich dadurch (wie soll ich sagen) die "items" selbst erzeugen auf der GUI.