c# Deserialize XML nested collections - c#

Hi I have some XML I wish to deserialise to .NET POCOs using the XMLSerializer
the xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<message uuid="{2f1e274c-6a53-afea-3047-6dc739539656}">
<envelope received="a_date" subject="a_name">
<from>
<monitor name="Local Folder" user_description="" uuid="{668DC658-97D7-42c8-AE72-ED289DD02355}"/>
</from>
<to>
<account>
<factory name="a_name"/>
</account>
</to>
</envelope>
<status>
<action name="Folder" occured="a_date" type="monitor">
<session completed="a_date" name="a_name" started="a_date"/>
</action>
<action occured="a_date" type="monitor"/>
<action occured="a_date" type="translate">
<session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="time"/>
<session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="time"/>
</action>
<action occured="a_date" type="deliver">
<session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="byte"/>
<session completed="a_date" name="a_name" started="a_date" unit="byte"/>
<session completed="a_date" current="a_number" name="a_name" started="a_date" total="a_number" unit="byte"/>
</action>
<action occured="a_date" type="complete"/>
</status>
<host name="a_name"/>
</message>
Within the xml, I have a status section which contains a collection of actions, each action may contain a collection of sessions.
I have created classes for the XMLSerialiser to deserialize the xml:
namespace myNameSpace
{
[XmlRoot("message")]
public class message
{
[XmlAttribute("uuid")]
public string uuid { get; set; }
[XmlElement("envelope")]
public envelope envelope { get; set; }
[XmlArray("status")]
[XmlArrayItem(typeof(action))]
public ObservableCollection<action> status { get; set; }
[XmlElement("host")]
public host host { get; set; }
}
public class envelope
{
[XmlAttribute("received")]
public string received { get; set; }
[XmlAttribute("subject")]
public string subject { get; set; }
[XmlElement("from")]
public from from { get; set; }
[XmlElement("to")]
public to to { get; set; }
}
#region envelope element definitions
public class from
{
[XmlElement("monitor")]
public monitor monitor { get; set; }
}
public class monitor
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("user_description")]
public string user_description { get; set; }
[XmlAttribute("uuid")]
public string uuid { get; set; }
}
public class to
{
[XmlElementAttribute("account")]
public account account { get; set; }
}
public class account
{
[XmlElementAttribute("factory")]
public factory factory { get; set; }
}
public class factory
{
[XmlAttribute("name")]
public string name { get; set; }
}
#endregion
public class action
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("occured")]
public string occured { get; set; }
[XmlAttribute("type")]
public string type { get; set; }
[XmlArray("action")]
[XmlArrayItem(typeof(session))]
public ObservableCollection<session> session { get; set; }
}
public class session
{
[XmlAttribute("completed")]
public string completed { get; set; }
[XmlAttribute("current")]
public long current { get; set; }
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("started")]
public string started { get; set; }
[XmlAttribute("total")]
public long total { get; set; }
[XmlAttribute("unit")]
public string unit { get; set; }
}
public class host
{
[XmlAttribute("name")]
public string name { get; set; }
}
}
Mostly I get the object graph I desire with all the values correctly deserialzed, but I can not find a way to get the XMLSerialiser to deserialize the session collection within an action element - The are always empty.
Does anyone know how I might build my POCOs so that the XMLserialiser can create the session collections?
best regards
John.

This was generated using xsd.exe. Hope this helps.
using System.Xml.Serialization;
using System.Xml.Schema;
using System;
[SerializableAttribute()]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class message
{
[XmlElementAttribute("envelope", Form = XmlSchemaForm.Unqualified)]
public messageEnvelope[] envelope { get; set; }
[XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
[XmlArrayItemAttribute("action", typeof(messageStatusAction), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
public messageStatusAction[][] status { get; set; }
[XmlElementAttribute("host", Form = XmlSchemaForm.Unqualified)]
public messageHost[] host { get; set; }
[XmlAttributeAttribute()]
public string uuid { get; set; }
}
[SerializableAttribute()]
public partial class messageEnvelope
{
[XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
[XmlArrayItemAttribute("monitor", typeof(messageEnvelopeFromMonitor), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
public messageEnvelopeFromMonitor[][] from { get; set; }
[XmlArrayAttribute(Form = XmlSchemaForm.Unqualified)]
[XmlArrayItemAttribute("account", typeof(messageEnvelopeTOAccountFactory[]), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
[XmlArrayItemAttribute("factory", typeof(messageEnvelopeTOAccountFactory), Form = XmlSchemaForm.Unqualified, IsNullable = false, NestingLevel = 1)]
public messageEnvelopeTOAccountFactory[][][] to { get; set; }
[XmlAttributeAttribute()]
public string received { get; set; }
[XmlAttributeAttribute()]
public string subject { get; set; }
}
[SerializableAttribute()]
public partial class messageEnvelopeFromMonitor
{
[XmlAttributeAttribute()]
public string name { get; set; }
[XmlAttributeAttribute()]
public string user_description { get; set; }
[XmlAttributeAttribute()]
public string uuid { get; set; }
}
[SerializableAttribute()]
public partial class messageEnvelopeTOAccountFactory
{
[XmlAttributeAttribute()]
public string name { get; set; }
}
[SerializableAttribute()]
public partial class messageStatusAction
{
[XmlElementAttribute("session", Form = XmlSchemaForm.Unqualified)]
public messageStatusActionSession[] session { get; set; }
[XmlAttributeAttribute()]
public string name { get; set; }
[XmlAttributeAttribute()]
public string occured { get; set; }
[XmlAttributeAttribute()]
public string type { get; set; }
}
[SerializableAttribute()]
public partial class messageStatusActionSession
{
[XmlAttributeAttribute()]
public string completed { get; set; }
[XmlAttributeAttribute()]
public string name { get; set; }
[XmlAttributeAttribute()]
public string started { get; set; }
[XmlAttributeAttribute()]
public string current { get; set; }
[XmlAttributeAttribute()]
public string total { get; set; }
[XmlAttributeAttribute()]
public string unit { get; set; }
}
[SerializableAttribute()]
public partial class messageHost
{
[XmlAttributeAttribute()]
public string name { get; set; }
}
[SerializableAttribute()]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{
[XmlElementAttribute("message")]
public message[] Items { get; set; }
}

First, session must inherit action.
Then you might need to replace public ObservableCollection<action> status { get; set; } by public List<action> status { get; set; } or public action[] status { get; set; } (I don't if ObservableCollection is considered XmlSerializable).
Finally, you may have to add the [XmlInclude(typeof(session))] on the action class declaration.

I believe your problem is once you are at the action level, you cant specify it as the XmlArray Type. That would be the sessions. Give this a try and see if it works:
public class action
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("occured")]
public string occured { get; set; }
[XmlAttribute("type")]
public string type { get; set; }
[XmlArray(typeof(session))]
public ObservableCollection<session> session { get; set; }
}

Related

Xml deserialization returns empty array even though POCO has right xml attributes generated from xsd2code++ tool

I am using XSD2Code++ 2019 tool for visual studio to generate POCOs from aset of 5 xsds. I have added the POCO class below. I see that it has the right xml decorators for it to serialize properly. But I really fail to understand or figure out why the 3rd level object in the returned deserialized data is always empty and not typecasted to the correct type.
I have tried changing attributes to xmlArray and xmlArrayElement too but none of that worked.
POCO class-
https://gist.github.com/nimisha84/b86a4bb2bf37aea6ec351a9f6e331bed
Sample xml response which has null values after deserialization using c# code-
<?xml version="1.0" encoding="UTF-8"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2019-07-05T14:29:08.603-07:00">
<QueryResponse startPosition="1" maxResults="1" totalCount="1">
<Invoice domain="QBO" sparse="false">
<Id>8633</Id>
<SyncToken>14</SyncToken>
<MetaData>
<CreateTime>2019-01-09T11:32:12-08:00</CreateTime>
<LastUpdatedTime>2019-06-05T12:49:40-07:00</LastUpdatedTime>
</MetaData>
<CustomField>
<DefinitionId>1</DefinitionId>
<Name>CustomPO</Name>
<Type>StringType</Type>
<StringValue>Gold</StringValue>
</CustomField>
<DocNumber>2830</DocNumber>
<TxnDate>2019-01-09</TxnDate>
<CurrencyRef name="United States Dollar">USD</CurrencyRef>
<ExchangeRate>1</ExchangeRate>
<PrivateNote>Voided - Voided</PrivateNote>
<Line>
<Id>1</Id>
<LineNum>1</LineNum>
<Description>Description</Description>
<Amount>0</Amount>
<DetailType>SalesItemLineDetail</DetailType>
<SalesItemLineDetail>
<ItemRef name="Name27140">815</ItemRef>
<Qty>0</Qty>
<TaxCodeRef>NON</TaxCodeRef>
</SalesItemLineDetail>
</Line>
<Line>
<Amount>0</Amount>
<DetailType>SubTotalLineDetail</DetailType>
<SubTotalLineDetail />
</Line>
<TxnTaxDetail>
<TotalTax>0</TotalTax>
</TxnTaxDetail>
<CustomerRef name="a4">2561</CustomerRef>
<DueDate>2019-01-09</DueDate>
<TotalAmt>0</TotalAmt>
<HomeTotalAmt>0</HomeTotalAmt>
<ApplyTaxAfterDiscount>false</ApplyTaxAfterDiscount>
<PrintStatus>NeedToPrint</PrintStatus>
<EmailStatus>NotSet</EmailStatus>
<Balance>0</Balance>
<Deposit>0</Deposit>
<AllowIPNPayment>false</AllowIPNPayment>
<AllowOnlinePayment>false</AllowOnlinePayment>
<AllowOnlineCreditCardPayment>false</AllowOnlineCreditCardPayment>
<AllowOnlineACHPayment>false</AllowOnlineACHPayment>
</Invoice>
</QueryResponse>
</IntuitResponse>
Code to deserialize-
string responseText = apiResponse.ReadToEnd();
var responseSerializer = new XmlObjectSerializer();
IntuitResponse restResponse =
(IntuitResponse)this.responseSerializer.Deserialize<IntuitResponse>(responseText);
res=restResponse.Items[0] as QueryResponse;
here QueryResponse is not having Invoice(of type IntuitEntity) object returned. Instead empty value is returned. See screenshot.
https://imgur.com/a/5yF6Khb
I really need help to figure out why the 3rd level property is returned as empty.
I tested code below and it works. I manually generated the classes which produces simpler results than using tools.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string responseText = File.ReadAllText(FILENAME);
StringReader reader = new StringReader(responseText);
XmlReader xReader = XmlReader.Create(reader);
XmlSerializer serializer = new XmlSerializer(typeof(IntuitResponse));
IntuitResponse response = (IntuitResponse)serializer.Deserialize(xReader);
}
}
[XmlRoot(ElementName = "IntuitResponse", Namespace = "http://schema.intuit.com/finance/v3")]
public class IntuitResponse
{
[XmlAttribute("time")]
public DateTime time { get; set; }
[XmlElement(ElementName = "QueryResponse", Namespace = "http://schema.intuit.com/finance/v3")]
public QueryResponse response { get; set; }
}
public class QueryResponse
{
[XmlAttribute("startPosition")]
public int startPosition { get; set; }
[XmlAttribute("maxResults")]
public int maxResults { get; set; }
[XmlAttribute("totalCount")]
public int totalCount { get; set; }
[XmlElement(ElementName = "Invoice", Namespace = "http://schema.intuit.com/finance/v3")]
public Invoice invoice { get; set; }
}
public class Invoice
{
[XmlAttribute("domain")]
public string domain { get; set; }
[XmlAttribute("sparse")]
public Boolean sparse { get; set; }
public int Id { get; set; }
public int SyncToken { get; set; }
[XmlElement(ElementName = "MetaData", Namespace = "http://schema.intuit.com/finance/v3")]
public MetaData metaData { get; set; }
[XmlElement(ElementName = "CustomField", Namespace = "http://schema.intuit.com/finance/v3")]
public CustomField customField { get; set; }
public int DocNumber { get; set; }
public DateTime TxnDate { get; set; }
[XmlElement(ElementName = "CurrencyRef", Namespace = "http://schema.intuit.com/finance/v3")]
public CurrencyRef currencyRef { get; set; }
public int ExchangeRate { get; set; }
public string PrivateNote { get; set; }
[XmlElement(ElementName = "Line", Namespace = "http://schema.intuit.com/finance/v3")]
public List<Line> line { get; set; }
[XmlElement(ElementName = "TxnTaxDetail", Namespace = "http://schema.intuit.com/finance/v3")]
public TxnTaxDetail txnTaxDetail { get; set; }
[XmlElement(ElementName = "CustomerRef", Namespace = "http://schema.intuit.com/finance/v3")]
public CustomerRef CustomerRef { get; set; }
public DateTime DueDate { get; set; }
public int TotalAmt { get; set; }
public int HomeTotalAmt { get; set; }
public Boolean ApplyTaxAfterDiscount { get; set; }
public string PrintStatus { get; set; }
public string EmailStatus { get; set; }
public int Balance { get; set; }
public int Deposit { get; set; }
public Boolean AllowIPNPayment { get; set; }
public Boolean AllowOnlinePayment { get; set; }
public Boolean AllowOnlineCreditCardPayment { get; set; }
public Boolean AllowOnlineACHPayment { get; set; }
}
public class MetaData
{
public DateTime CreateTime { get; set; }
public DateTime LastUpdatedTime { get; set; }
}
public class CustomField
{
public int DefinitionId { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string StringValue { get; set; }
}
public class CurrencyRef
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlText]
public string value { get; set; }
}
public class Line
{
public int Id { get; set; }
public int LineNum { get; set; }
public string Description { get; set; }
public decimal Amount { get; set; }
public string DetailType { get; set; }
[XmlElement(ElementName = "SalesItemLineDetail", Namespace = "http://schema.intuit.com/finance/v3")]
public SalesItemLineDetail salesItemLineDetail { get; set; }
}
public class CustomerRef
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlText]
public string value { get; set; }
}
public class SalesItemLineDetail
{
[XmlElement(ElementName = "ItemRef", Namespace = "http://schema.intuit.com/finance/v3")]
public ItemRef itemRef { get; set; }
public int Qty { get; set; }
public string TaxCodeRef { get; set; }
}
public class ItemRef
{
[XmlAttribute("name")]
public string name { get; set; }
[XmlText]
public string value { get; set; }
}
public class TxnTaxDetail
{
public int TotalTax { get; set; }
}
}

How to fix my list of objects being serialized improperly

I have been having an issue to serialize an object properly. I have an object SensorSession which looks like:
[XmlRoot("Session")]
public class SensorSession
{
[XmlElement("SensorDefinitionCollection")]
public SensorDefinitionCollection mCollection { get; set; }
[XmlElement("SensorRunner")]
public SensorRunner mRunner { set; get; }
}
public class SensorDefinitionCollection : IEnumerable<SensorDefinition>
{
[XmlArray("SensorDefinitionCollection")]
[XmlArrayItem("SensorDefinition")]
public List<SensorDefinition> mCollection;
}
public class SensorDefinition : IEquatable<SensorDefinition>, IComparable<SensorDefinition>
{
[XmlElement("StartingWavelength")]
public double startingWavelength { get; set; }
[XmlElement("StoppingWavelength")]
public double stoppingWavelength { get; set; }
[XmlElement("TargetWavelength")]
public double targetWavelength { get; set; }
}
When I serialize I get the following:
<?xml version="1.0" encoding="utf-8"?>
<Session xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SensorDefinitionCollection>
<StartingWavelength>1300</StartingWavelength>
<StoppingWavelength>1400</StoppingWavelength>
<TargetWavelength>1350</TargetWavelength>
</SensorDefinitionCollection>
<SensorDefinitionCollection>
<StartingWavelength>1200</StartingWavelength>
<StoppingWavelength>1300</StoppingWavelength>
<TargetWavelength>1250</TargetWavelength>
</SensorDefinitionCollection>
<SensorRunner>
<SensorConfig>
<SampleCount>5</SampleCount>
<SampleDelay>5</SampleDelay>
<SampleTolerance>5</SampleTolerance>
</SensorConfig>
</SensorRunner>
</Session>
But What I expect to get is this:
<?xml version="1.0" encoding="utf-8"?>
<Session xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SensorDefinitionCollection>
<SensorDefinition>
<StartingWavelength>1200</StartingWavelength>
<StoppingWavelength>1300</StoppingWavelength>
<TargetWavelength>1250</TargetWavelength>
</SensorDefinition>
</SensorDefinitionCollection>
<SensorRunner>
<SensorConfig>
<SampleCount>5</SampleCount>
<SampleDelay>5</SampleDelay>
<SampleTolerance>5</SampleTolerance>
</SensorConfig>
</SensorRunner>
</Session>
How do I allow for the list (SensorDefinitionCollection) to become a single element, and all the SensorDefinitions in that list to fall inside?
UPDATE:
The issue has been resolved with a little refactoring. Rather than having the collection object contain the list, the object inherits List with the definition objects.
[XmlRoot("Session")]
public class SensorSession
{
[XmlArray("SensorDefinitionCollection")]
[XmlArrayItem("SensorDefinition")]
public SensorDefinitionCollection Collection { get; set; }
[XmlElement("SensorRunner")]
public SensorRunner mRunner { set; get; }
}
[Serializable()]
public class SensorDefinitionCollection : List<SensorDefinition>
{
}
public class SensorDefinition : IEquatable<SensorDefinition>, IComparable<SensorDefinition>
{
[XmlElement("StartingWavelength")]
public double startingWavelength { get; set; }
[XmlElement("StoppingWavelength")]
public double stoppingWavelength { get; set; }
[XmlElement("TargetWavelength")]
public double targetWavelength { get; set; }
}
This should help you with that,
[XmlRoot(ElementName = "SensorDefinition")]
public class SensorDefinition
{
[XmlElement(ElementName = "StartingWavelength")]
public int StartingWavelength { get; set; }
[XmlElement(ElementName = "StoppingWavelength")]
public int StoppingWavelength { get; set; }
[XmlElement(ElementName = "TargetWavelength")]
public int TargetWavelength { get; set; }
}
[XmlRoot(ElementName = "SensorDefinitionCollection")]
public class SensorDefinitionCollection
{
[XmlElement(ElementName = "SensorDefinition")]
public List<SensorDefinition> SensorDefinition { get; set; }
}
[XmlRoot(ElementName = "SensorConfig")]
public class SensorConfig
{
[XmlElement(ElementName = "SampleCount")]
public int SampleCount { get; set; }
[XmlElement(ElementName = "SampleDelay")]
public int SampleDelay { get; set; }
[XmlElement(ElementName = "SampleTolerance")]
public int SampleTolerance { get; set; }
}
[XmlRoot(ElementName = "SensorRunner")]
public class SensorRunner
{
[XmlElement(ElementName = "SensorConfig")]
public List<SensorConfig> SensorConfig { get; set; }
}
[XmlRoot(ElementName = "Session")]
public class SensorSession
{
[XmlElement(ElementName = "SensorDefinitionCollection")]
public List<SensorDefinitionCollection> SensorDefinitionCollection { get; set; }
[XmlElement(ElementName = "SensorRunner")]
public List<SensorRunner> SensorRunner { get; set; }
}

C# InnerXml of XmlElement deserialization

I have inner XML that looks like:
<approving xmlns="uz:rwc:fdu-92:1.0">
<fdu92>
<general num="25120001" date="25.12.2013" payment_kind="tehpd" sum="22200" />
<station code="370006" name="Test" road_short_name="Test" />
<cargo-owner code="7765" name="Test Subject" />
<payer code="7395392" name="Test Subject" />
<references>
<reference num="11111" doc_name="soma document">
<payments>
<payment code="158" subcode="001" name="Some work" reason="unknown" sum="22200" expended_count="1" />
</payments>
</reference>
</references>
</fdu92>
</approving>
<signature xmlns="uz:rwc:fdu-92:1.0">Many thousands of symbols</signature>
When I am trying to build classes from Xml by online tool xml to classes
it return Invalid Xml.
Because it has
<signature xmlns="uz:rwc:fdu-92:1.0">Many thousands of symbols</signature>
Converting without tag
<signature xmlns="uz:rwc:fdu-92:1.0">Many thousands of symbols</signature>
gives good result
namespace Xml2CSharp
{
[XmlRoot(ElementName="general", Namespace="uz:rwc:fdu-92:1.0")]
public class General {
[XmlAttribute(AttributeName="num")]
public string Num { get; set; }
[XmlAttribute(AttributeName="date")]
public string Date { get; set; }
[XmlAttribute(AttributeName="payment_kind")]
public string Payment_kind { get; set; }
[XmlAttribute(AttributeName="sum")]
public string Sum { get; set; }
}
[XmlRoot(ElementName="station", Namespace="uz:rwc:fdu-92:1.0")]
public class Station {
[XmlAttribute(AttributeName="code")]
public string Code { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
[XmlAttribute(AttributeName="road_short_name")]
public string Road_short_name { get; set; }
}
[XmlRoot(ElementName="cargo-owner", Namespace="uz:rwc:fdu-92:1.0")]
public class Cargoowner {
[XmlAttribute(AttributeName="code")]
public string Code { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="payer", Namespace="uz:rwc:fdu-92:1.0")]
public class Payer {
[XmlAttribute(AttributeName="code")]
public string Code { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="payment", Namespace="uz:rwc:fdu-92:1.0")]
public class Payment {
[XmlAttribute(AttributeName="code")]
public string Code { get; set; }
[XmlAttribute(AttributeName="subcode")]
public string Subcode { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
[XmlAttribute(AttributeName="reason")]
public string Reason { get; set; }
[XmlAttribute(AttributeName="sum")]
public string Sum { get; set; }
[XmlAttribute(AttributeName="expended_count")]
public string Expended_count { get; set; }
}
[XmlRoot(ElementName="payments", Namespace="uz:rwc:fdu-92:1.0")]
public class Payments {
[XmlElement(ElementName="payment", Namespace="uz:rwc:fdu-92:1.0")]
public Payment Payment { get; set; }
}
[XmlRoot(ElementName="reference", Namespace="uz:rwc:fdu-92:1.0")]
public class Reference {
[XmlElement(ElementName="payments", Namespace="uz:rwc:fdu-92:1.0")]
public Payments Payments { get; set; }
[XmlAttribute(AttributeName="num")]
public string Num { get; set; }
[XmlAttribute(AttributeName="doc_name")]
public string Doc_name { get; set; }
}
[XmlRoot(ElementName="references", Namespace="uz:rwc:fdu-92:1.0")]
public class References {
[XmlElement(ElementName="reference", Namespace="uz:rwc:fdu-92:1.0")]
public Reference Reference { get; set; }
}
[XmlRoot(ElementName="fdu92", Namespace="uz:rwc:fdu-92:1.0")]
public class Fdu92 {
[XmlElement(ElementName="general", Namespace="uz:rwc:fdu-92:1.0")]
public General General { get; set; }
[XmlElement(ElementName="station", Namespace="uz:rwc:fdu-92:1.0")]
public Station Station { get; set; }
[XmlElement(ElementName="cargo-owner", Namespace="uz:rwc:fdu-92:1.0")]
public Cargoowner Cargoowner { get; set; }
[XmlElement(ElementName="payer", Namespace="uz:rwc:fdu-92:1.0")]
public Payer Payer { get; set; }
[XmlElement(ElementName="references", Namespace="uz:rwc:fdu-92:1.0")]
public References References { get; set; }
}
[XmlRoot(ElementName="approving", Namespace="uz:rwc:fdu-92:1.0")]
public class Approving {
[XmlElement(ElementName="fdu92", Namespace="uz:rwc:fdu-92:1.0")]
public Fdu92 Fdu92 { get; set; }
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
}
}
When I am trying to deserialize the object
DeserializeFromXmlElement<Approving>(FDU92Xml);
public static T DeserializeFromXmlElement<T>(XmlElement element)
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new XmlNodeReader(element));
}
I get an error
xml document contains error
How to fix error? How to ignore signature in deserialization process?

C# deserialization CBISDDStsRptPhyMsg

I need to deserialize a XML that follows the CBI Italian standard, the problem is that I've already marked every class with the namespace's but I'm still unable to deserialize.
This is part of the xml that I'm trying to deserialize (content erased):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RISPOSTASDD:CBISDDStsRptPhyMsg xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07" xmlns:BODY="urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00" xmlns:SGNT="urn:CBI:xsd:CBISgnInf.001.04" xmlns:RISPOSTASDD="urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00" xmlns:LMSG="urn:CBI:xsd:CBISDDStsRptLogMsg.00.01.00" xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07">
<RISPOSTASDD:CBIHdrTrt>
<HTRT:IdCBISndrf></HTRT:IdCBISndrf>
<HTRT:IdCBIRcvrf></HTRT:IdCBIRcvrf>
<HTRT:SrvNm></HTRT:SrvNm>
<HTRT:IdMsgTrt></HTRT:IdMsgTrt>
<HTRT:XMLCrtDt></HTRT:XMLCrtDt>
<HTRT:RtrnAddrl></HTRT:RtrnAddrl>
</RISPOSTASDD:CBIHdrTrt>
<RISPOSTASDD:CBIHdrSrv>
<HE2E:SrvInfo>
<HE2E:SrvNm></HE2E:SrvNm>
<HE2E:IdE2EMsg></HE2E:IdE2EMsg>
<HE2E:XMLCrtDt></HE2E:XMLCrtDt>
</HE2E:SrvInfo>
<HE2E:Sender>
<HE2E:IdCBISend></HE2E:IdCBISend>
<HE2E:SendTyp></HE2E:SendTyp>
<HE2E:CBIRefrSend></HE2E:CBIRefrSend>
</HE2E:Sender>
<HE2E:Receiver>
<HE2E:IdCBIRecv></HE2E:IdCBIRecv>
<HE2E:RecvTyp></HE2E:RecvTyp>
<HE2E:CBIRefrRecv></HE2E:CBIRefrRecv>
</HE2E:Receiver>
<HE2E:DiagInfo>
<HE2E:UsrBnk></HE2E:UsrBnk>
<HE2E:DiagVers></HE2E:DiagVers>
<HE2E:ChkSbj></HE2E:ChkSbj>
<HE2E:ChkDt></HE2E:ChkDt>
</HE2E:DiagInfo>
<HE2E:CongrInfo>
<HE2E:SrvBdyNb></HE2E:SrvBdyNb>
</HE2E:CongrInfo>
</RISPOSTASDD:CBIHdrSrv>
<RISPOSTASDD:CBIBdySDDStsRpt>
<BODY:PhyMsgInf>
<BODY:PhyMsgTpCd></BODY:PhyMsgTpCd>
<BODY:NbOfLogMsg></BODY:NbOfLogMsg>
</BODY:PhyMsgInf>
<BODY:CBIEnvelSDDStsRptLogMsg>
<BODY:CBISDDStsRptLogMsg>...
And these are (some) the classes that I've wrote to deserialize it:
[Serializable, XmlRoot(Namespace = "urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00")]
public class CBISDDStsRptPhyMsg
{
[XmlElement("CBIHdrTrt", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public CBIHdrTrt CBIHdrTrt {get;set;}
[XmlElement("CBIHdrSrv", Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public CBIHdrSrv CBIHdrSrv {get;set;}
[XmlElement("CBIBdySDDStsRpt", Namespace="urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00")]
public CBIBdySDDStsRpt CBIBdySDDStsRpt { get; set; }
}
[Serializable]
public class CBIHdrTrt
{
[XmlElement("IdCBISndrf", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public string IdCBISndrf { get; set; }
[XmlElement("IdCBIRcvrf", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public string IdCBIRcvrf { get; set; }
[XmlElement("SrvNm", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public string SrvNm { get; set; }
[XmlElement("IdMsgTrt", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public string IdMsgTrt { get; set; }
[XmlElement("XMLCrtDt", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public DateTime XMLCrtDt { get; set; }
[XmlElement("RtrnAddrl", Namespace = "urn:CBI:xsd:CBIHdrTrt.001.07")]
public string RtrnAddrl { get; set; }
}
[Serializable]
public class CBIHdrSrv
{
[XmlElement("SrvInfo",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public SrvInfo SrvInfo { get; set; }
[XmlElement("Sender",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public Sender Sender { get; set; }
[XmlElement("Receiver",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public Receiver Receiver { get; set; }
[XmlElement("DiagInfo",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public DiagInfo DiagInfo { get; set; }
[XmlElement("CongrInfo",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public CongrInfo CongrInfo { get; set; }
}
[Serializable]
public class SrvInfo
{
[XmlElement("SrvNm",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string SrvNm { get; set; }
[XmlElement("IdE2EMsg",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string IdE2EMsg { get; set; }
[XmlElement("XMLCrtDt",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public DateTime XMLCrtDt { get; set; }
}
[Serializable]
public class Sender
{
[XmlElement("IdCBISend",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string IdCBISend { get; set; }
[XmlElement("SendTyp",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string SendTyp { get; set; }
[XmlElement("CBIRefrSend",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string CBIRefrSend { get; set; }
}
[Serializable]
public class Receiver
{
[XmlElement("IdCBIRecv",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string IdCBIRecv { get; set; }
[XmlElement("RecvTyp",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string RecvTyp { get; set; }
[XmlElement("CBIRefrRecv",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string CBIRefrRecv { get; set; }
}
[Serializable]
public class DiagInfo
{
[XmlElement("UsrBnk",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string UsrBnk { get; set; }
[XmlElement("DiagVers",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string DiagVers { get; set; }
[XmlElement("ChkSbj",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public string ChkSbj { get; set; }
[XmlElement("ChkDt",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public DateTime ChkDt { get; set; }
}
[Serializable]
public class CongrInfo
{
[XmlElement("SrvBdyNb",Namespace="urn:CBI:xsd:CBIHdrSrv.001.07")]
public int SrvBdyNb { get; set; }
}
[Serializable]
public class CBIBdySDDStsRpt
{
[XmlElement("PhyMsgInf", Namespace = "urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00")]
public PhyMsgInf PhyMsgInf { get; set; }
[XmlElement("CBIEnvelSDDStsRptLogMsg", Namespace = "urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00")]
public CBIEnvelSDDStsRptLogMsg CBIEnvelSDDStsRptLogMsg { get; set; }
}
[Serializable]
public class CBIEnvelSDDStsRptLogMsg
{
[XmlElement("CBISDDStsRptLogMsg", Namespace = "urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00")]
public CBISDDStsRptLogMsg CBISDDStsRptLogMsg { get; set; }
}
[Serializable]
public class CBISDDStsRptLogMsg
{
[XmlElement("GrpHdr", Namespace = "urn:CBI:xsd:CBISDDStsRptLogMsg.00.01.00")]
public GroupHeader GroupHeader { get; set; }
[XmlElement("OrgnlGrpInfAndSts", Namespace = "urn:CBI:xsd:CBISDDStsRptLogMsg.00.01.00")]
public OriginalGroupInformationAndStatus OriginalGroupInformationAndStatus { get; set; }
[XmlElement("OrgnlPmtInfAndSts", Namespace = "urn:CBI:xsd:CBISDDStsRptLogMsg.00.01.00")]
public List<OriginalPaymentInformationAndStatus> OriginalPaymentInformationAndStatus { get; set; }
}
My deserialization is pretty simple:
var sITA = new XmlSerializer(typeof(CBISDDStsRptPhyMsg));
var xmlITA = new CBISDDStsRptPhyMsg();
using(var reader = XmlReader.Create(fileInput.InputStream))
{
xmlITA = (CBISDDStsRptPhyMsg)sITA.Deserialize(reader);
}
and at the end of it, all of my 3 main objects are null.
Does anyone have a clue on what I'm doing wrong? I've already managed to serialize/deserialize every SEPA files (pain.00x) that I've found but this Italian standard is giving me quite some head-aches for a while.
Does anyone have the classes that are able to deserialize this italian standard? (Don't bother on finding the .xsd to generate it because I've already googled quite a bit and the .xsd is nowhere to be found!)
Thanks in advance.
The three child elements of the root element in the same namespace as the root, the one prefixed RISPOSTASDD:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RISPOSTASDD:CBISDDStsRptPhyMsg xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07" xmlns:BODY="urn:CBI:xsd:CBIBdySDDStsRpt.00.01.00" xmlns:SGNT="urn:CBI:xsd:CBISgnInf.001.04" xmlns:RISPOSTASDD="urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00" xmlns:LMSG="urn:CBI:xsd:CBISDDStsRptLogMsg.00.01.00" xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07">
<RISPOSTASDD:CBIHdrTrt>
<!-- Nested elements snipped -->
</RISPOSTASDD:CBIHdrTrt>
<RISPOSTASDD:CBIHdrSrv>
<!-- Nested elements snipped -->
</RISPOSTASDD:CBIHdrSrv>
<RISPOSTASDD:CBIBdySDDStsRpt>
<!-- Remaining XML not included in the question -->
Thus your root class needs to be modified as follows:
[Serializable, XmlRoot(Namespace = "urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00")]
public class CBISDDStsRptPhyMsg
{
[XmlElement("CBIHdrTrt", Namespace = "urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00")]
public CBIHdrTrt CBIHdrTrt { get; set; }
[XmlElement("CBIHdrSrv", Namespace = "urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00")]
public CBIHdrSrv CBIHdrSrv { get; set; }
[XmlElement("CBIBdySDDStsRpt", Namespace = "urn:CBI:xsd:CBISDDStsRptPhyMsg.00.01.00")]
public CBIBdySDDStsRpt CBIBdySDDStsRpt { get; set; }
}
(Or you could just omit the Namespace = on the properties since it's the same as in the XmlRoot attribute.)
There may be other problems, but your question doesn't contain a full mcve (the XML and classes are both incomplete) but at the minimum this looks incorrect.

Deserialize xml xmpp message to object

I'm trying to deserialize a xml string to a c# object. This is the message:
<message from='test1#localhost' to='test2#localhost'><result xmlns='urn:xmpp:mam:tmp' id='A6QV1I4TKO81'><forwarded xmlns='urn:xmpp:forward:0'><delay xmlns='urn:xmpp:delay' from='test1#localhost' stamp='2015-07-21T09:12:09Z'></delay><message type='mchat'><subject/><body/></message></forwarded></result></message>
And this is the class
public class Delay {
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName="from")]
public string From { get; set; }
[XmlAttribute(AttributeName="stamp")]
public string Stamp { get; set; }
}
public class Active {
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
}
public class XmppMessage {
[XmlElement(ElementName="body")]
public string Body { get; set; }
[XmlAttribute(AttributeName="lang")]
public string Lang { get; set; }
[XmlAttribute(AttributeName="type")]
public string Type { get; set; }
[XmlAttribute(AttributeName="id")]
public string Id { get; set; }
[XmlAttribute(AttributeName="to")]
public string To { get; set; }
}
public class Forwarded {
[XmlElement(ElementName="delay")]
public Delay Delay { get; set; }
[XmlElement(ElementName="message")]
public XmppMessage Message { get; set; }
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
}
public class Result {
[XmlElement(ElementName="forwarded")]
public Forwarded Forwarded { get; set; }
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName="id")]
public string Id { get; set; }
}
[XmlRoot(ElementName="message")]
public class MessageHistory {
[XmlElement(ElementName="result")]
public Result Result { get; set; }
[XmlAttribute(AttributeName="from")]
public string From { get; set; }
[XmlAttribute(AttributeName="to")]
public string To { get; set; }
}
This is the code to deserialise:
MessageHistory messageNode;
XmlSerializer serializer = new XmlSerializer(typeof(MessageHistory));
using (StringReader reader = new StringReader(message))
{
messageNode = (MessageHistory)(serializer.Deserialize(reader));
}
The object property "from" and "to" are fine but the "Result" is returning null. I can't understand what I'm missing here...
The problem is the namespaces in the XML. you have to specify the namespaces explicitly, like this:
public class Forwarded
{
[XmlElement(ElementName = "delay", Namespace = "urn:xmpp:delay")]
public Delay Delay { get; set; }
[XmlElement(ElementName = "message")]
public XmppMessage Message { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
}
public class Result
{
[XmlElement(ElementName = "forwarded", Namespace = "urn:xmpp:forward:0")]
public Forwarded Forwarded { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "message")]
public class MessageHistory
{
[XmlElement(ElementName = "result", Namespace = "urn:xmpp:mam:tmp")]
public Result Result { get; set; }
[XmlAttribute(AttributeName = "from")]
public string From { get; set; }
[XmlAttribute(AttributeName = "to")]
public string To { get; set; }
}

Categories