Ваша проблема в том, что ваша модель данных c # не соответствует вашему XML.В частности:
Вы указали, что имя элемента для DiagnosisErrorResponse
должно быть "ns0:transmission"
.Префикс пространства имен ns0:
должен быть включен , а не , это просто поиск в файле XML для поиска фактического пространства имен, которое определяется атрибутом xmlns xmlns:ns0="blabla.xsd"
.
XML имеет уровень вложенности, не учитываемый в вашей модели данных.XML в вашем вопросе не имеет отступов;если я сделаю отступ, то это будет выглядеть так:
<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>
Как теперь видно, ID
и т. д. не являются детьми transmission
, они являются детьми DiagnosisErrorResponse
, который является потомкомtransmission
.Это необходимо учитывать в ваших классах c #.
Сочетая эти две проблемы, ваша модель данных должна выглядеть следующим образом:
[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; }
}
И ваш код десериализации должен выглядетьнапример:
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;
}
}
Демо-скрипта # 1 здесь .
В качестве альтернативы, если вы пытались десериализовать только элемент <DiagnosisErrorResponse>
внутри XML-файла без созданияМодель данных для корневого элемента, вы можете использовать XmlReader
для сканирования вперед в XML, пока не будет найден соответствующий элемент:
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;
}
}
Демонстрационная скрипка # 2 здесь .
Примечания:
Нет необходимости загружать файл XML в XmlDocument
, повторно сериализовать его как строку, а затем десериализовать строку.XML может быть десериализован непосредственно из файла за один шаг, используя XmlReader
или StreamReader
.
XmlTextReader
устарел Microsoft в своей документации .XmlReader.Create()
следует использовать вместо.
Вы можете избежать ошибок моделирования, таких как описанные выше, используя один из инструментов генерации кода, упомянутых в GenerateКласс C # из XML .
Самый простой способ диагностировать ошибку десериализации XML - это сериализовать экземпляр вашего корневого типа, а затем сравнить полученный результатXML с XML для десериализации.Несоответствия, как правило, легко обнаруживаются и указывают на наличие проблем.