Problem with deserializing a message with substitutionGroup - c#

I have the following XML message that I deserialize with XmlSerializer.
For some reasons, deserialization of this message strips the Database section of the XML message.
I need some help in deserializing this message in its entirety.
This is a sample test XML message.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Radars xmlns="http://mycompany.com/2008/c2s2">
<Radar>
<Identification>
<Identifier>140:141</Identifier>
<IP>10.216.1.79</IP>
<Label>Radar 1</Label>
<Model>Radar123</Model>
<Category>Civil</Category>
</Identification>
<Database>
<Radar456General>
<Identifier>203</Identifier>
<Version>8</Version>
<RadarStartStop>false</RadarStartStop>
<AntennaRotationSpeed>false</AntennaRotationSpeed>
<RadarAntennaRotation>false</RadarAntennaRotation>
<AntennaStaringPosition>0</AntennaStaringPosition>
</Radar456General>
</Database>
</Radar>
</Radars>
I am using XmlSerializer to deserialize the above message like this:
public static T Deserialize<T>(string message)
{
object obj = null;
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
StringReader reader = new StringReader(message);
XmlTextReader xmlReader = new XmlTextReader(reader);
obj = xs.Deserialize(xmlReader);
xmlReader.Close();
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw ex;
}
return (T)obj;
}
Radars radars = Serializer.Deserialize<Radars>(message);
After deserializing it, I get an empty Database section (meaning radars.radar[0].Database.Length == 0).
The schema of the message is specified in a separate XSD file. I use xsd.exe to generate C# classes from it.
This is the partial content of the XSD file.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://mycompany.com/2008/c2s2"
targetNamespace="http://mycompany.com/2008/c2s2"
elementFormDefault="qualified" version="1.0">
<xs:include schemaLocation="asterix_cat034.xsd"/>
<xs:include schemaLocation="asterix_cat253.xsd"/>
<xs:element name="Radars">
<xs:annotation>
<xs:documentation>List of radar information</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Radar" type="RadarType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="RadarType">
<xs:sequence>
<xs:element name="Identification" type="RadarIdentificationType"/>
<xs:element name="Database" type="DatabaseType"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Radar" type="RadarType"/>
<xs:complexType name="RadarIdentificationType">
<xs:annotation>
<xs:documentation>
This type represents the radar identification.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="Identifier" type="xs:string"/>
<xs:element name="IP" type="xs:string"/>
<xs:element name="Label" type="xs:string"/>
<xs:element name="Model" type="RadarModelType"/>
<xs:element name="Category" type="RadarCategoryType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="RadarModelType">
<xs:restriction base="xs:string">
<xs:enumeration value="Radar123"/>
<xs:enumeration value="Radar456"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RadarCategoryType">
<xs:restriction base="xs:string">
<xs:enumeration value="Civil"/>
<xs:enumeration value="Military"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="DatabaseSectionType">
<xs:sequence>
<xs:element name="Identifier" type="xs:unsignedByte"/>
<xs:element name="Version" type="I253_100_DB_VER"/>
</xs:sequence>
</xs:complexType>
<xs:element name="DatabaseSectionType" type="DatabaseSectionType">
<xs:annotation>
<xs:documentation>root of the substitution group</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="DatabaseType">
<xs:sequence>
<xs:element ref="DatabaseSectionType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Radar456General" substitutionGroup="DatabaseSectionType">
<xs:annotation>
<xs:documentation>Radar456General database section</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:complexContent>
<xs:extension base="DatabaseSectionType">
<xs:sequence>
<xs:element name="RadarStartStop" type="I253_100_Start_Stop"/>
<xs:element name="AntennaRotationSpeed" type="I253_100_ARS"/>
<xs:element name="RadarAntennaRotation" type="I253_100_ROT"/>
<xs:element name="AntennaStaringPosition" type="I253_100_ASP"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="Radar123General" substitutionGroup="DatabaseSectionType">
<xs:annotation>
<xs:documentation>Radar123General database section</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:complexContent>
<xs:extension base="DatabaseSectionType">
<xs:sequence>
<xs:element name="Shutdown" type="I253_100_Shutdown"/>
<xs:element name="RotationTransmission" type="I253_100_ROT_TX"/>
<xs:element name="SurfaceInstrumentedRange" type="I253_100_SIR"/>
<xs:element name="TransmitterTuneMode" type="I253_100_TT_mode"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
So how can I deserialize the message with Database section?

Try create the same object structure in code, serialize it and see he differences between your data and serialized date, than you'll know whats wrong.

Related

XSD2Code - Create a List of Objects when generate a class

I've created this XSD schema and I want to use XSD2Code to generate code. The problem I'm facing happens when I try to have a list of objects. It cannot recognize the complex type.
XSD Example:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="INVOICE01">
<xs:complexType>
<xs:sequence>
<xs:element name="Test" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="nome" minOccurs="0" type="xs:string" ></xs:element>
<xs:element name="nome2" minOccurs="0" type="xs:string" ></xs:element>
<xs:element name="henrique">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="henrique1" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
If I don't use the maxOccurs="unbounded" it work fine.

How do I access xsd value using xpath

I have the following xsd file...
<?xml version="1.0" encoding="Windows-1252"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="order">
<xs:complexType>
<xs:sequence>
<xs:element name="ordername" maxOccurs="1" minOccurs="1" type="xs:string" />
<xs:element name="articles">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="article">
<xs:complexType>
<xs:sequence>
<xs:element name="Account" maxOccurs="1" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="1|5|7|9"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Vat" maxOccurs="1" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="1|2|3"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I am trying to access all allowed patterns for a specific element. In this case I would like to find the allowed pattern for "Account" which should give me "1|5|7|9". Ideally I would like to be able to directly access the value, something like this...
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(fileName);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema");
var nodeToAccess = xmlDoc.DocumentElement.SelectSingleNode("order/articles/article/Account", nsmgr);
But that does not work, can anyone please show the proper way to do this?
You can use XPath for this:
var nodeToAccess = xmlDoc.SelectSingleNode("//xs:element[#name='Account']/xs:simpleType/xs:restriction/xs:pattern", nsmgr);
if (nodeToAccess != null)
{
Console.WriteLine(nodeToAccess.Attributes["value"].Value);
}

Using XSD in a WCF web service generating extra tags

I have a xsd file that defines the request of my service. So I used xsd.exe to generate a c# class for this service.
This is the xsd file:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="schemaConectividade">
<xs:complexType>
<xs:choice>
<xs:element name="conectividadeParaOperadora" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="cabecalhoTransacao" type="ct_cabecalhoTransacao"/>
<xs:element name="dadosSolicitacao">
<xs:complexType>
<xs:sequence>
<xs:element name="atendimentoRN" type="xs:string"/>
<xs:element name="beneficiario">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="executante" type="xs:long"/>
<xs:element name="solicitante" type="xs:long"/>
<xs:element name="profissionalSolicitante" type="ct_profissionalSolicitante"/>
<xs:element name="caraterAtendimento" type="xs:int"/>
<xs:element name="procedimentosSolicitados">
<xs:complexType>
<xs:sequence>
<xs:element name="procedimento" type="ct_procedimento" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="operadoraParaConectividade" minOccurs="0">
<xs:complexType>
<xs:choice>
<xs:element name="retornoSchema" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="descricaoSchemaErro" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="retornoNegocio" type="ct_retornoNegocio" minOccurs="0"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="ct_dadosTransacao">
<xs:sequence>
<xs:element name="horaTransacao" type="xs:time"/>
<xs:element name="dataTransacao" type="xs:date"/>
<xs:element name="numeroTransacao" type="xs:long"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ct_retornoNegocio">
<xs:sequence>
<xs:element name="statusRetorno">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="dadosTransacao" type="ct_dadosTransacao"/>
<xs:element name="transacaoErro" type="ct_transacaoErro" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ct_transacaoErro">
<xs:sequence>
<xs:element name="descricaoErro" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ct_cabecalhoTransacao">
<xs:sequence>
<xs:element name="numeroTransacao" type="xs:long"/>
<xs:element name="numeroAtendimento" type="xs:long"/>
<xs:element name="dataTransacao" type="xs:date"/>
<xs:element name="horaTransacao" type="xs:time"/>
<xs:element name="tipoTransacao" type="xs:integer"/>
<xs:element name="terminal" type="xs:long" minOccurs="0"/>
<xs:element name="tipoTerminal" type="xs:string" minOccurs="0"/>
<xs:element name="fonteDadosBeneficiario" type="xs:string" minOccurs="0"/>
<xs:element name="fonteDadosPrestador" type="xs:string" minOccurs="0"/>
<xs:element name="centralAtendimento" type="xs:long" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ct_profissionalSolicitante">
<xs:sequence>
<xs:element name="nomeProfissional" type="xs:string"/>
<xs:element name="conselhoProfissional" type="xs:string"/>
<xs:element name="numeroConselhoProfissional" type="xs:int"/>
<xs:element name="UF" type="xs:string"/>
<xs:element name="CBOS" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ct_procedimento">
<xs:sequence>
<xs:element name="sequencialProcedimento" type="xs:integer"/>
<xs:element name="dataAtendimento" type="xs:date"/>
<xs:element name="quantidade" type="xs:integer"/>
<xs:element name="procedimento" type="xs:string"/>
<xs:element name="situacaoTransacao" type="xs:string"/>
<xs:element name="mensagem" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and this is the interface generated:
using System.ServiceModel;
namespace MyNamespace
{
[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface IOrizon
{
[System.ServiceModel.OperationContract]
[System.ServiceModel.XmlSerializerFormatAttribute()]
ResponseType TransacaoAex_Operation(RequestType conectividadeParaOperadora);
}
}
When using SoapUI to test this service, it generates a "TransacaoAex_Operation" tag, that is not in my xsd file:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<TransacaoAex_Operation>
<conectividadeParaOperadora>
...
There is a way to avoid this?

Error adding schema to XmlSchemaSet

I am trying to add an xsd into an XmlSchemaSet but get the following error "Data at the root level is invalid. Line 1, position 1."
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(new StringReader(#"C:\source\Net4\Clocks\Handlers\XML_Schemas\test.xsd")));
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="interface">
<xs:complexType>
<xs:sequence>
<xs:element name="node1" type="xs:string" />
<xs:element name="node2" type="xs:string" />
<xs:element name="node3" type="xs:string" />
<xs:element name="node4" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="node5" type="xs:unsignedByte" />
<xs:element name="node6">
<xs:complexType>
<xs:sequence>
<xs:element name="node6" type="xs:dateTime" />
<xs:element name="node7" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
You need to pass contents of a file into StringReader, not the path to a file.
var pathToFile = #"C:\source\Net4\Clocks\Handlers\XML_Schemas\test.xsd";
var reader = new StringReader(File.ReadAllText(pathToFile));
schemas.Add("", XmlReader.Create(reader));
Alternativ way to add reader to XmlSchemaSet is
schemas.Add("", new XmlTextReader(pathToFile));

Problem deserializing xml file

I auto generated an xsd file from the below xml and used xsd2code to get a c# class. The problem is the entire xml doesn't deserialize.
Here is how I'm attempting to deserialize:
static void Main(string[] args)
{
using (TextReader textReader = new StreamReader("config.xml"))
{
// string temp = textReader.ReadToEnd();
XmlSerializer deserializer = new XmlSerializer(typeof(project));
project p = (project)deserializer.Deserialize(textReader);
}
}
here is the actual XML:
<?xml version='1.0' encoding='UTF-8'?>
<project>
<scm class="hudson.scm.SubversionSCM">
<locations>
<hudson.scm.SubversionSCM_-ModuleLocation>
<remote>https://svn.xxx.com/test/Validation/CPS DRTest DLL/trunk</remote>
</hudson.scm.SubversionSCM_-ModuleLocation>
</locations>
<useUpdate>false</useUpdate>
<browser class="hudson.scm.browsers.FishEyeSVN">
<url>http://fisheye.xxxx.net/browse/Test/</url>
<rootModule>Test</rootModule>
</browser>
<excludedCommitMessages></excludedCommitMessages>
</scm>
<openf>Hello there</openf>
<buildWrappers/>
</project>
When I run the above, the locations node remains null.
Here is the xsd that I'm using:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="project">
<xs:complexType>
<xs:all>
<xs:element name="openf" type="xs:string" minOccurs="0" />
<xs:element name="buildWrappers" type="xs:string" minOccurs="0" />
<xs:element name="scm" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="useUpdate" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
<xs:element name="excludedCommitMessages" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="locations" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="hudson.scm.SubversionSCM_-ModuleLocation" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="remote" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="browser" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="rootModule" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="project" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Figured it out. When using xsd2code I had select options to target the 3.5 framework and include the xml attributes. It now deserializes as expected. Not sure which one did it, but works now.
According to this page '.' is not a valid XML tag name character, so you need to rename <hudson.scm.SubversionSCM_-ModuleLocation> to something without the dots.

Categories

Resources