Your problem is that your c# data model does not match your XML. Specifically:
You have indicated that the element name for DiagnosisErrorResponse
should be "ns0:transmission"
. The namespace prefix ns0:
should not be included, it is just a lookup in the XML file to find the actual namespace, which is defined by the xmlns attribute xmlns:ns0="blabla.xsd"
.
The XML has a level of nesting not accounted for in your data model. The XML in your question is not indented; if I indent it, it looks like:
<ns0:transmission xmlns:ns0="blabla.xsd">
<ns0:DiagnosisErrorResponse>
<ns0:ID>7</ns0:ID>
<ns0:ErrorCode>9</ns0:ErrorCode>
<ns0:ErrorDescription>sometext</ns0:ErrorDescription>
<ns0:ErrorDate>11-12-2018</ns0:ErrorDate>
</ns0:DiagnosisErrorResponse>
</ns0:transmission>
As can now be seen, ID
and so on are not children of transmission
, they are children of DiagnosisErrorResponse
which is a child of transmission
. This needs to be accounted for in your c# classes.
Combining these two issues, your data model should look like:
[XmlRoot(Namespace = "blabla.xsd", ElementName = "transmission", IsNullable = true)]
public class Transmission
{
[XmlElement("DiagnosisErrorResponse")]
public DiagnosisErrorResponse DiagnosisErrorResponse { get; set; }
}
[XmlRoot(Namespace = "blabla.xsd", IsNullable = true)]
public class DiagnosisErrorResponse
{
[XmlElement("ID")]
public long ID { get; set; }
[XmlElement("ErrorCode")]
public int ErrorCode { get; set; }
[XmlElement("ErrorDescription")]
public string ErrorDescription { get; set; }
[XmlElement("ErrorDate")]
public string ErrorDate { get; set; }
}
And your deserialization code should look like:
private DiagnosisErrorResponse ReadXmlFileByPath(string filePath)
{
using (var xmlReader = XmlReader.Create(filePath))
{
XmlSerializer xs = new XmlSerializer(typeof(Transmission));
var result = (Transmission)xs.Deserialize(xmlReader);
return result.DiagnosisErrorResponse;
}
}
Demo fiddle #1 here.
Alternatively, if you were trying to deserialize just the <DiagnosisErrorResponse>
element inside the XML file without creating a data model for the root element, you could use XmlReader
to scan forward in the XML until the appropriate element is found:
private DiagnosisErrorResponse ReadXmlFileByPath(string filePath)
{
using (var xmlReader = XmlReader.Create(filePath))
{
if (!xmlReader.ReadToDescendant("DiagnosisErrorResponse", "blabla.xsd"))
return null;
XmlSerializer xs = new XmlSerializer(typeof(DiagnosisErrorResponse));
var result = (DiagnosisErrorResponse)xs.Deserialize(xmlReader);
return result;
}
}
Demo fiddle #2 here.
Notes:
There is no need to load the XML file into an XmlDocument
, re-serialize it as a string, then deserialize the string. The XML can be deserialized directly from a file in one step using an XmlReader
or StreamReader
.
XmlTextReader
has been deprecated by Microsoft in its documentation. XmlReader.Create()
should be used instead.
You can avoid modeling errors such as the ones above by using one of the code generation tools mentioned in Generate C# class from XML.
The easiest way to diagnose an error in XML deserialization is to serialize an instance of your root type, then compare the resulting XML with the XML to be deserialized. Inconsistencies are typically easily spotted and indicate where you have problems.