[closed - danke] XSD.exe probleme?
-
Hallo,
ersmal zur problem beschreibung: ich will ein objekt (XML) einlesen, daten analysieren, eventuell etwas ändern und wieder herausschreiben.
um das zu erereichen will ich XSD.exe einsetzen (sollte, als standardtool von VS10, stabil laufen). ich nehme also meine schema definition und generiere mit folgendem befehl meine c# klasse(n):xsd.exe /n:egon /c /l:cs c:\xsds\egon.xsd /o:c:\generatedClasses\
heraus kommt meine egon.cs, die ich beim serialisieren/deserialisieren einsetzen kann:
class EgonPrg { public static void Main(string[] args) { TextReader reader = new StreamReader("egon.xml"); StreamWriter writer = new StreamWriter("egon_out.xml"); XmlSerializer ser = new XmlSerializer(typeof(egon.egon)); egon.egon eee = (egon.egon) ser.Deserialize(reader); reader.Close(); ser.Serialize(writer.BaseStream, eee); } }
um mein vorhaben zu validieren habe ich eine einfache, gültige XML generiert, die ich einfach deserialisiere und wieder serialisiere. das ergebnis sind aber unterschiedliche dateninhalte!!!
kann mir da jemand einen ansatz liefern was da schief läuft? ich durchschaue das leider nicht und bin mir nicht sicher ob XmlSerialise bzw XSD.exe oder irgendwas in meinem Programm nicht korrekt arbeitet.
unten ist das egon.xsd beispiel zu finden (+ das original und das de- + serialisierte XML).Grüße
evil user
<?xml version="1.0" encoding="UTF-8"?> <!-- edited with XMLSpy v2011 rel. 3 sp1 (x64) (http://www.altova.com) by meeeeeeeeee --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="foobar" type="egon"/> <xs:complexType name="egon"> <xs:sequence> <xs:element name="skin" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="note" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="shades" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="modern" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="expensive" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="a"/> <xs:enumeration value="b"/> <xs:enumeration value="c"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="classic" type="xs:string" minOccurs="0"/> <xs:choice minOccurs="0"> <xs:element name="color"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="color2"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="a"/> <xs:enumeration value="b"/> <xs:enumeration value="c"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="uv-protection" type="xs:string"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="figure" type="xs:boolean" minOccurs="0"/> <xs:element name="strength" type="xs:int" minOccurs="0"/> <xs:element name="appearance" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:int"/> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="clothes" minOccurs="0"> <xs:complexType> <xs:choice> <xs:element name="shirt" type="xs:float"/> <xs:element name="trowsers" type="xs:boolean"/> <xs:element name="shoes" type="xs:boolean"/> </xs:choice> </xs:complexType> </xs:element> <xs:element name="hair" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:float"> <xs:minExclusive value="0.2"/> <xs:maxExclusive value="30.0"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:choice> <xs:element name="courage" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:float"> <xs:minExclusive value="0.2"/> <xs:maxExclusive value="30.0"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="cowardice" type="xs:boolean" minOccurs="0"/> </xs:choice> <xs:element name="speed" default="a" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="a"/> <xs:enumeration value="c"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="charisma" type="xs:boolean" minOccurs="0"/> <xs:element name="diplomacy" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:boolean"> <xs:attribute name="level" type="xs:float"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="sociopathy" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:boolean"> <xs:attribute name="level"> <xs:simpleType> <xs:restriction base="xs:float"> <xs:minInclusive value="1.3"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:choice minOccurs="0"> <xs:element name="intelligent" type="xs:boolean"/> <xs:element name="dumb" type="xs:boolean"/> </xs:choice> <xs:choice minOccurs="0"> <xs:element name="famous" type="xs:float"/> <xs:element name="prominent" type="xs:float"/> <xs:element name="known" type="xs:string"/> <xs:element name="normal" type="xs:string"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:schema>
<?xml version="1.0" encoding="UTF-8"?> <foobar/>
<?xml version="1.0"?> <foobar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <dumb>false</dumb> </foobar>
-
Servus,
das Output ist richtig. Der XMLSerializer knallt dir halt an das Rootelement den XML-Namespace mit dran. Um das zu Umgehen verwende ein "leeren" Namespace:
/// <summary> /// Generic type XML serialisation. /// </summary> /// <typeparam name="T">Serialise defined type</typeparam> /// <param name="data">Input data</param> /// <returns>Returns serialised XML as byte[] if it succeeded, otherwise null.</returns> public static byte[] SerializeXml<T>(T data) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); byte[] rawdata = null; try { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); using (MemoryStream stream = new MemoryStream()) { xmlSerializer.Serialize(stream, data, ns); rawdata = stream.ToArray(); } } catch { return null; } return rawdata; }
So sieht meine Methode aus.
Gruß
Hellsgore
-
Hallo Hellsgore,
danke erstmal für deine Antwort und ja, dein Vorschlag funktioniert. Der Namespace verschwindet wenn ich ein XmlSerialiserNamespaces definiere. Das erspart mir einige unterschiede im DIFF.
<?xml version="1.0"?> <foobar> <dumb>false</dumb> </foobar>
Mein Problem ist aber das dumb=false das da plötzlich entsteht. In der original Eingabe habe ich doch nichts angegeben.
Grüße
evil user
-
Sofern dumb eine Property von Egon ist und du keinen Wert vergibst, ist Egon.dumb = false. Somit wird der Wert false beim Serialisieren geschrieben.
// EDIT:
Nach meiner Theorie müsste für intelligent ebenfalse false geschrieben worden sein.
-
Hallo,
Du meinst also, dass beim deserialisieren dumb und intelligent standardmäßig false eingetragen bekommen. auch wenn sie nicht gesetzt sind (die choice ist optional, minOccurs=0). Wenn der Serialiser dann beim herausschreiben auf dumb==false stößt (per sequenz der elemente im XSD vor intelligent) nimmt er an, dass das element geändert wurde und jetzt gesetzt ist.
Das ist nicht korrekt. Danke für den Hinweis. Ich werde das mal mit einigen anderen Werten probieren (xs:int oder xs:string oder so) und nachsehen ob das problem bestehen bleibt.Grüße
evil user
-
Die boolschen Properties bekommen garnichts gesetzt. Ein bool kennt nur zwei Zustände, true und false. Da du dem Wert nie ein true zuweist, ist er eben false. Und da die Property mit false auch einen Wert hat, wird dieser beim serialisieren geschrieben.
-
Hallo Inflames2k,
Ich habe das mal mit int probiert und da besteht das selbe problem. Du liegst also richtig. es gibt also 2 lösungen. zum einen kann ich das choice element in egon.cs von bool auf object ändern (läuft dann korrekt), oder ich passe das XSD an.
Danke nochmals!
Grüße
evil user
-
<xs:element name="skin" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="note" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="shades" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="modern" minOccurs="0"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="expensive" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="a"/> <xs:enumeration value="b"/> <xs:enumeration value="c"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="classic" type="xs:string" minOccurs="0"/> <xs:choice minOccurs="0"> <xs:element name="color"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="color2"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="a"/> <xs:enumeration value="b"/> <xs:enumeration value="c"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="uv-protection" type="xs:string"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element>
XML muss man doch einfach hassen....