none
XmlSerializer und Liste von Elementen RRS feed

  • Frage

  • Hallo,

     

    ich muss folgendes File schreiben.

     

    Mein Ziel:

    <CodeList operator="xnk">
    	<Job assembly="" assemblyRev="" name="202382" batch="" lot="">
    		<Barcode scanTime="2016-05-11T13:37:17.00+01:00" id="">
    			<TwoDCode scanTime="2017-28-11T13:37:17.00+01:00" id="GGGGTest-0004-001" />
    			<TwoDCode scanTime="2017-28-11T13:37:17.00+01:00" id="GGGGTest-0004-002" />
    			<TwoDCode scanTime="2017-28-11T13:37:17.00+01:00" id="GGGGTest-0004-003" />
    			<TwoDCode scanTime="2017-28-11T13:37:17.00+01:00" id="GGGGTest-0004-004" />
    			<TwoDCode scanTime="2017-28-11T13:37:17.00+01:00" id="GGGGTest-0004-005" />

    Leider funktioniert es nicht.

    Sobald ich den XmlSerializer serializer = new XmlSerializer(typeof(CodeList));

    aufrufe, erhalte ich eine Exception.

     

       --> Fehler beim Reflektieren.

      

     Kann mir bitte jemand sagen, wie ich die Klassen korrekt anlegen muss,

     damit die Liste gemäß der Vorgabe serialisiert werden kann?

     

     <CodeList operator="DDD">
      <Job assembly="" assemblyRev="" name="dddd" batch="" lot="">
        <Barcode scanTime="" id="" />
      </Job>
    </CodeList>

     

     Vielen Dank.

     

     Grüße Sandra.


    [Serializable]
    // [XmlRoot("CodeList")]
    public class TwoDCode
    {
    	[XmlAttribute("scanTime")]
    	public string ScanTime { get; set; }
    
    	[XmlAttribute("id")]
    	public string Id { get; set; }
    
    	public TwoDCode(string scanTime, string id)
    	{
    		ScanTime = scanTime;
    		Id = id;
    	}
    }
    
    [Serializable]
    public class Barcode
    {
    	// ATTRIBUTES
    	[XmlAttribute("scanTime")]
    	public string ScanTime { get; set; }
    
    	[XmlAttribute("id")]
    	public string Id { get; set; }
    
    	// ELEMENTS
    	//[XmlElement("TwoDCode")]
    	[XmlArray("Barcode"), XmlArrayItem(typeof(TwoDCode), ElementName = "TwoDCode")]
    	public List<TwoDCode> ListTwoDCode { get; set; }
    
    	public void Append(string scanTime, string id)
    	{
    	  //  ListTwoDCode.Add(new TwoDCode(scanTime, id));
    	}
    
    	// CONSTRUCTOR
    	public Barcode()
    	{
    		ScanTime = "";
    		Id = "";
    
    		ListTwoDCode = new List<TwoDCode>();
    	}
    }

    // komplette Funktion
     public void SaveInfosXML<T>(string file, T dataObject)
    {
    	XmlSerializer serializer = new XmlSerializer(typeof(T));
    
    	using (Stream stream = new FileStream(file, FileMode.Create))
    	using (XmlWriter xmlWriter = XmlWriter.Create(stream, MyWriterSettings)) // 
    	{
    		serializer.Serialize(xmlWriter, dataObject, Namespaces);
    	}
    }		


    • Bearbeitet Sandra Bauer Freitag, 28. April 2017 16:28 Format
    Freitag, 28. April 2017 16:27

Antworten

  • Hi,

    gar nicht. Zumindest nicht für das, was Du oben haben willst.

    Wenn Du um die einzelnen Elemente der Liste einen weiteren Node einbauen willst, bspw. so:

    <?xml version="1.0" encoding="utf-8"?>
    <CodeList operator="operatorX">
        <Job assembly="assemblyX" assemblyRev="assemblyRevX" name="nameX" batch="batchX" lot="lotX">
            <Barcode scanTime="29.04.2017 13:14:13" id="idX">
                <ItemList>
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX1" />
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX2" />
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX3" />
                </ItemList>
            </Barcode>
        </Job>
    </CodeList>

    kannst Du in der Klasse "Barcode" die Eigenschaft "Items" so deklarieren:

    [XmlArray( "ItemList" )]
    public List<TwoDCode> Items { get; set; }
    


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert Sandra Bauer Montag, 1. Mai 2017 14:31
    Samstag, 29. April 2017 11:16
    Moderator

Alle Antworten

  • Hi,

    probier es mal so:

    using System;
    using System.Xml.Serialization;
    using System.Collections.Generic;
    
    public class CodeList
    {
        public Job Job { get; set; }
        
        [XmlAttribute( "operator" )]
        public String Operator { get; set; }
    
        public CodeList()
        {
            this.Job = new Job();
        }
    }
    
    public class Job
    {
        [XmlAttribute( "assembly" )]
        public String Assembly { get; set; }
    
        [XmlAttribute( "assemblyRev" )]
        public String AssemblyRev { get; set; }
    
        [XmlAttribute( "name" )]
        public String Name { get; set; }
    
        [XmlAttribute( "batch" )]
        public String Batch { get; set; }
    
        [XmlAttribute( "lot" )]
        public String Lot { get; set; }
    
        [XmlElement( "Barcode" )]
        public Barcode Barcode { get; set; }
    
        public Job()
        {
            this.Barcode = new Barcode();
        }
    }
    
    public class Barcode
    {
        [XmlAttribute( "scanTime" )]
        public String ScanTime { get; set; }
    
        [XmlAttribute( "id" )]
        public String ID { get; set; }
    
        [XmlElement( "TwoDCode" )]
        public List<TwoDCode> Items { get; set; }
    
        public Barcode()
        {
            this.Items = new List<TwoDCode>();
        }
    }
    
    public class TwoDCode
    {
        [XmlAttribute( "scanTime" )]
        public String ScanTime { get; set; }
    
        [XmlAttribute( "id" )]
        public String ID { get; set; }
    
        public TwoDCode()
            :this( String.Empty, String.Empty )
        {
        }
    
        public TwoDCode( string scanTime, string id )
        {
            this.ScanTime = scanTime;
            this.ID       = id;
        }
    }

    Mit folgendem Code die Instanz von CodeList aufgebaut:

    CodeList codeList = new CodeList();
    codeList.Operator        = "operatorX";
    
    codeList.Job.Assembly    = "assemblyX";
    codeList.Job.AssemblyRev = "assemblyRevX";
    codeList.Job.Name        = "nameX";
    codeList.Job.Batch       = "batchX";
    codeList.Job.Lot         = "lotX";
    
    codeList.Job.Barcode.ScanTime = DateTime.Now.ToString();
    codeList.Job.Barcode.ID       = "idX";
    
    codeList.Job.Barcode.Items.Add( new TwoDCode( DateTime.Now.ToString(), "idX1" ) );
    codeList.Job.Barcode.Items.Add( new TwoDCode( DateTime.Now.ToString(), "idX2" ) );
    codeList.Job.Barcode.Items.Add( new TwoDCode( DateTime.Now.ToString(), "idX3" ) );


    wird folgender XML Aufbau erzeugt:

    <?xml version="1.0" encoding="utf-8"?>
    <CodeList operator="operatorX">
        <Job assembly="assemblyX" assemblyRev="assemblyRevX" name="nameX" batch="batchX" lot="lotX">
            <Barcode scanTime="29.04.2017 12:02:58" id="idX">
                <TwoDCode scanTime="29.04.2017 12:02:58" id="idX1" />
                <TwoDCode scanTime="29.04.2017 12:02:58" id="idX2" />
                <TwoDCode scanTime="29.04.2017 12:02:58" id="idX3" />
            </Barcode>
        </Job>
    </CodeList>

    welche dann beim Deserialisieren auch wieder korrekt eingelesen wird. (Wobei ich natürlich meine Serialisierungs- und Deserialisierungsmethoden verwendet habe, die hab ich dir in früheren Postings ja schon mehrfach gezeigt)

    ---

    Bzgl. der Fehlermeldung: Bitte schau in die InnerException oder (was besser wäre) poste die vollständige und exakte Fehlermeldung, ggfs. mit <Exception>.ToString(). In der InnerException steht in der Regel drin, was nicht funktioniert hat.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community




    Samstag, 29. April 2017 10:04
    Moderator
  • Hallo Stefan,

    Danke für Deine Antwort. Ich werde es prüfen. Hab's genau so gemacht.

    Dann habe ich mit dem XmlArray rumgespielt etc. Wann immer man das dann braucht.

    // ELEMENTS
    	//[XmlElement("TwoDCode")]
    	[XmlArray("Barcode"), XmlArrayItem(typeof(TwoDCode), ElementName = "TwoDCode")]
    	public List<TwoDCode> ListTwoDCode { get; set; }
    


    Du hast hier einen leeren Konstruktor genommen.

    public TwoDCode()
            :this( String.Empty, String.Empty )
        {
        }
    

    Das hatte ich nicht.

    Grüße Sandra

    Samstag, 29. April 2017 10:54
  • Hi,

    bei Serialisierungsklassen (bzw. eigentlich immer) erstelle ich immer einen Standardkonstruktor ohne Parameter. Ohne den geht es bei der (De)Serialisierung IIRC nicht.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Samstag, 29. April 2017 10:57
    Moderator
  • bei Serialisierungsklassen (bzw. eigentlich immer) erstelle ich immer einen Standardkonstruktor ohne Parameter. Ohne den geht es bei der (De)Serialisierung IIRC nicht.



    Hallo Stefan,

    ok Danke. So einfach wieder. 

    Aber wann müßte ich das dann so machen? Also mit XmlArray.

    // ELEMENTS 
    //[XmlElement("TwoDCode")]
    [XmlArray("Barcode"), XmlArrayItem(typeof(TwoDCode), ElementName = "TwoDCode")] 
    public List<TwoDCode> ListTwoDCode { get; set; } 

    Viele Grüße Sandra


    • Bearbeitet Sandra Bauer Samstag, 29. April 2017 11:11 Format
    Samstag, 29. April 2017 11:10
  • Hi,

    gar nicht. Zumindest nicht für das, was Du oben haben willst.

    Wenn Du um die einzelnen Elemente der Liste einen weiteren Node einbauen willst, bspw. so:

    <?xml version="1.0" encoding="utf-8"?>
    <CodeList operator="operatorX">
        <Job assembly="assemblyX" assemblyRev="assemblyRevX" name="nameX" batch="batchX" lot="lotX">
            <Barcode scanTime="29.04.2017 13:14:13" id="idX">
                <ItemList>
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX1" />
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX2" />
                    <TwoDCode scanTime="29.04.2017 13:14:13" id="idX3" />
                </ItemList>
            </Barcode>
        </Job>
    </CodeList>

    kannst Du in der Klasse "Barcode" die Eigenschaft "Items" so deklarieren:

    [XmlArray( "ItemList" )]
    public List<TwoDCode> Items { get; set; }
    


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert Sandra Bauer Montag, 1. Mai 2017 14:31
    Samstag, 29. April 2017 11:16
    Moderator
  • Hallo Stefan,

    ja Danke für die schnelle Antwort.

    Viele Grüße Sandra

    Samstag, 29. April 2017 12:20