Probleme mit der Serialisierung einer Klasse, um XML-und sogar mit einem CDATA-Abschnitt

Habe ich eine Klasse, die serialisiert in XML-für den Konsum durch einen web-service. In diesem Klassen-Instanz, die XML muss ein CDATA-Abschnitt für den web-service, es zu Lesen, aber ich bin ratlos, wie um dies zu implementieren.

Die XML muss so Aussehen:

<UpdateOrderStatus> 
    <Action>2</Action> 
        <Value> 
            <![CDATA[ 
                <Shipment> 
                    <Header> 
                        <SellerID>
                            ...
             ]]>
         </Value>
 </UpdateOrderStatus>

Ich bin in der Lage zu generieren, die entsprechende XML-Datei, mit Ausnahme der CDATA-Teil.

Meiner Klasse Struktur sieht wie folgt aus:

public class UpdateOrderStatus
{
    public int Action { get; set; }


    public ValueInfo Value { get; set; }

    public UpdateOrderStatus()
    {
        Value = new ValueInfo();
    }


    public class ValueInfo
    {
        public ShipmentInfo Shipment { get; set; }

        public ValueInfo()
        {
            Shipment = new ShipmentInfo();
        }

        public class ShipmentInfo
        {
            public PackageListInfo PackageList { get; set; }
            public HeaderInfo Header { get; set; }
            public ShipmentInfo()
            {
                PackageList = new PackageListInfo();
                Header = new HeaderInfo();
            }

         ....

Habe ich einige Anregungen mit:

[XmlElement("node", typeof(XmlCDataSection))]

aber, dass eine Ausnahme verursacht

Habe ich auch schon versucht

 [XmlElement("Value" + "<![CDATA[")]

aber die resultierende XML ist falsch, zeigt

 <Value_x003C__x0021__x005B_CDATA_x005B_>
 ....
 </Value_x003C__x0021__x005B_CDATA_x005B_>

Kann jemand mir zeigen, was ich falsch mache, oder wo ich mit diesem zu gehen?

--Edit--

machen shipmentInfo serializable pro carlosfigueira funktioniert für die meisten Teil, aber ich habe das extra ? Zeichen in der resultierenden XML ( siehe post Schreiben Sie ein XML-fragment mit XmlWriterSettings und XmlSerializer gibt einen extra Charakter für details )

Als solche änderte ich das Schreiben von XML-Code-Methode:

public void WriteXml(XmlWriter writer)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");

                XmlWriterSettings settings = new XmlWriterSettings();

                settings.OmitXmlDeclaration = true;
                settings.Encoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false);
                settings.Indent = true;

                using (XmlWriter innerWriter = XmlWriter.Create(ms, settings))
                {
                    shipmentInfoSerializer.Serialize(innerWriter, this.Shipment,ns);
                    innerWriter.Flush();
                    writer.WriteCData(Encoding.UTF8.GetString(ms.ToArray()));
                }
            }
        }

Aber ich bin nicht immer eine Ausnahme:

System.InvalidOperationException: There was an error generating the XML document. ---> System.ArgumentException: '.', hexadecimal
value 0x00, is an invalid character.

--Edit --

Ausnahme wurde durch die Einbeziehung von meiner vorherigen serializeToString Methode. Da das entfernen, dass die CDATA-Ausgabe ist korrekt, außer für ein spacing Problem, aber ich bin auch immer ein namespace und xml-Deklaration sollte entfernt werden, indem die XML-Einstellungen angegeben. Ausgabe:

<?xml version="1.0"?>
<UpdateOrderStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Action>1</Action>
  <Value><![CDATA[< S h i p m e n t I n f o >
     < P a c k a g e L i s t >
         < P a c k a g e >
             < S h i p D a t e > 2 0 1 2 - 0 7 - 1 3 T 1 1 : 5 8 : 5 1 . 0 9 2 5 6 1 5 - 0 4 : 0 0 < /S h i p D a t e >
             < I t e m L i s t >
                 < I t e m >
                     < S h i p p e d Q t y > 0 < /S h i p p e d Q t y >
                 < /I t e m >
             < /I t e m L i s t >
         < /P a c k a g e >
     < /P a c k a g e L i s t >
     < H e a d e r >
         < S e l l e r I d > S h i p m e n t   h e a d e r < /S e l l e r I d >
         < S O N u m b e r > 0 < /S O N u m b e r >
     < /H e a d e r >
 < /S h i p m e n t I n f o > ]]></Value>
</UpdateOrderStatus>

Irgendwelche Ideen, um die BOM mit der neuen Klasse?

Bearbeiten--3 -- ERFOLG!

Habe ich umgesetzt vorgeschlagenen änderungen unten, und jetzt haben Sie die folgenden writer-Klassen und test-Methoden:

 UpdateOrderStatus obj = new UpdateOrderStatus();

        obj.Action = 1;
        obj.Value = new UpdateOrderStatus.ValueInfo();
        obj.Value.Shipment = new UpdateOrderStatus.ValueInfo.ShipmentInfo();
        obj.Value.Shipment.Header.SellerId = "Shipment header";
        obj.Value.Shipment.PackageList = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo();
        obj.Value.Shipment.PackageList.Package = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo.PackageInfo();
        obj.Value.Shipment.PackageList.Package.ShipDate = DateTime.Now;



        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.Encoding = new UTF8Encoding(false);
        settings.Indent = true;
        XmlSerializer xs = new XmlSerializer(typeof(UpdateOrderStatus));
        MemoryStream ms = new MemoryStream();


        XmlWriter writer = XmlWriter.Create(ms, settings);
        xs.Serialize(writer, obj, ns);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }


public void WriteXml(XmlWriter writer)
        {

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");

            XmlWriterSettings settings = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent = true;

            StringBuilder sb = new StringBuilder();
            using (XmlWriter innerWriter = XmlWriter.Create(sb, settings))
            {
                shipmentInfoSerializer.Serialize(innerWriter, this.Shipment, ns);
                innerWriter.Flush();
                writer.WriteCData(sb.ToString());
            }   
        }

Führt dies zu den folgenden XML-Code:

<UpdateOrderStatus>
  <Action>1</Action>
  <Value><![CDATA[<ShipmentInfo>
  <PackageList>
    <Package>
      <ShipDate>2012-07-13T14:05:36.6170802-04:00</ShipDate>
      <ItemList>
        <Item>
          <ShippedQty>0</ShippedQty>
        </Item>
      </ItemList>
    </Package>
  </PackageList>
  <Header>
    <SellerId>Shipment header</SellerId>
    <SONumber>0</SONumber>
  </Header>
</ShipmentInfo>]]></Value>
</UpdateOrderStatus>
Beachten Sie, dass CDATA-Abschnitt ist eine Flucht xml um Sie lesbarer zu machen. Der Inhalt von CDATA ist nicht Xml. <![CDATA[< - test />]]> ist ein äquivalent von &lt;test /&gt; Wenn Sie sicher sind, dass der Inhalt ist immer ein gültiges Xml-Dokument, das Sie sollten in der Lage sein pre-process-Dokument zu entfernen, CDATA und unescape den Inhalt der CDATA-Abschnitt. Beachten Sie, dass dies, wenn die Inhalte nicht gültige Xml wird das gesamte Dokument ungültig. Eine weitere option ist das IXmlSerializable implementieren, wie unten angemerkt, aber sobald Sie anfangen, es wird wachsen und werden schwer zu pflegen.

InformationsquelleAutor Robert H | 2012-07-13

Schreibe einen Kommentar