52556

xmlserializer not correctly deserializing schema with import

I've been trying to deserialize an xml file in C# with classes generated from schemas in xsd.exe. Unfortunately only part of the file is being properly deserialized, the rest is returned as null for reasons I can't work out.

My process is as follows: Starting with the myschema.xsd file from which the C# code is generated:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mc="myschema:common" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ttl="http://www.myuri.org/myschema" targetNamespace="http://www.myuri.org/myschema" elementFormDefault="qualified" attributeFormDefault="unqualified">

and the imported parentschema.xsd file is so:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:mc="myschema:common" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="myschema:common" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="toplevel"> <xs:complexType> <xs:sequence> <xs:element ref="mc:toplevel_header" minOccurs="0"/> <xs:element ref="mc:body"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="toplevel_header"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:anyURI"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="body" type="mc:body" abstract="true"/> <xs:complexType name="body"> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> <xs:element name="Entity" type="mc:Entity" abstract="true"/> <xs:complexType name="Entity" abstract="true"> <xs:attribute name="href" type="xs:anyURI" use="optional"/> </xs:complexType> </xs:schema>

I'm passing the two above schema files to xsd.exe:

>xsd.exe /c myschema.xsd parentschema.xsd

which generates a myschema_parentschema.cs file

To test it I'm trying to deserialize a sample xml file:

<?xml version=\"1.0\" encoding="UTF-8"?> <toplevel version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="myschema:common" xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> <toplevel_header> <name>MyName</name> </toplevel_header> <body id="body_1" xmlns=https://www.e-learn.cn/content/wangluowenzhang/"http://www.myuri.org/schema" xmlns:mc="myschema:common" xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> <Foo href="http://www.google.com"> </Foo> </body> </toplevel>

which I'm passing to the following XmlSerializer code, where reader is an XmlReader for the above xml file:

XmlSerializer xs = new XmlSerializer ( typeof ( toplevel ) ); object deserializedObject = xs.Deserialize( reader ); toplevel fooBar = (toplevel)deserializedObject; Assert.AreEqual( "MyName", fooBar.toplevel_header.name ); //passes OK Assert.IsNotNull( fooBar.body ); //<--------FAIL

Why does the deserialized object have a null body property, and how do I get it to deserialize the Foo element properly?

Answer1:

There's a typo in your parentschema.xsd. You're closing the <xs:element> tag prematurely for the body tag:

<xs:element name="body" type="mc:body" abstract="true"/>

You also define the body as abstract which I think is a mistake (if I'm reading the XML properly).

The whole definition (based on your XML) should look something like:

<xs:element name="body" type="mc:body" abstract="true"> <xs:complexType> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:sequence> <xs:element type="Foo" type="xs:anyURI" /> </xs:sequence> </xs:complexType> </xs:element>

Answer2:

I followed the same steps as you, and it looks like your schema and the XML file that you're deserializing are not matching. Here's what I did:

static void Main(string[] args) { var xs = new XmlSerializer(typeof(toplevel)); // test saving to xml first... var tl = new toplevel(); tl.toplevel_header = new toplevel_header(); tl.toplevel_header.name = "MyName"; tl.body = new body(); tl.body.id = "body id..."; // output to console first... var cw = Console.OpenStandardOutput(); xs.Serialize(cw, tl); Console.WriteLine(); Console.WriteLine(); // save to file... var fw = File.CreateText("test.xml"); xs.Serialize(fw, tl); fw.Close(); // read file... var fr = File.Open("test.xml", FileMode.Open, FileAccess.Read); var obj = xs.Deserialize(fr); var fooBar = (toplevel)obj; Console.WriteLine(fooBar.toplevel_header.name); Console.WriteLine(fooBar.body.id); Console.ReadLine(); }

The XML that the serializer generated was this:

<?xml version="1.0" encoding="utf-8"?> <toplevel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="myschema:common"> <toplevel_header> <name>MyName</name> </toplevel_header> <body id="body id..." /> </toplevel>

The XML clearly does not match the input XML file you are using... Hopefully this helps you along your way!

Answer3:

Looking at your sample xml I noticed a inconsistency which is the reason why the XmlSerializer is not coming up with what you expect:

<toplevel version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" ***xmlns="myschema:common"*** xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> <toplevel_header> <name>MyName</name> </toplevel_header> <body id="body_1" ***xmlns=https://www.e-learn.cn/content/wangluowenzhang/"http://www.myuri.org/schema"*** ***xmlns:mc="myschema:common"*** xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> <Foo href="http://www.google.com"> </Foo> </body> </toplevel>

In your toplevel element you are defining xmlns="myschema:common", and yet in your body element you are defining xmlns="http://www.myuri.org/schema" and the next line is xmlns:mc="myschema:common". This means that the Foo element inside of the body is under a different namespace and the XmlSerializer will not find the element. When I deleted the xmlns declaration in the body element and changed the xmlns:mc declaration to xmlns, like so:

<?xml version="1.0" encoding="UTF-8"?> <toplevel version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="myschema:common" xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> <toplevel_header> <name>MyName</name> </toplevel_header> <body id="body_1" xmlns="myschema:common" xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> <Foo href="http://www.google.com"> </Foo> </body> </toplevel>

Having adjusted the sample xml as indicated the XmlSerializer created the toplevel object with a non-null body inside of it.

Recommend

  • How to validate, on runtime, xml against xsd without save the xsd file on local folder?
  • Unexpected element while unmarshalling
  • Does the Xml Schema spec define the serialization of optional attributes with a default?
  • CXF/JAXB Code-first service: modify XMLSchemaType of inputs
  • Cannot assign “”: “Comment.user” must be a “MyProfile” instance
  • add an element to a node, if it doesnot exist
  • Doesnt stl sort require a strict weak ordering to work?
  • Reading in a seqence from a text file in Common Lisp
  • minOccurs and maxOccurs on elements inside xsd:choice
  • Python: matching values from one list to the sequence of values in another list
  • PyTorch: Relation between Dynamic Computational Graphs - Padding - DataLoader
  • NHibernate: Persist an object with children
  • “Drawing” an arc in discrete x-y steps
  • Select values within/outside of a set of intervals (ranges) R
  • Root element minOccurs or maxOccurs
  • How to get the max timestamp and groupby another field in LINQ to Entities
  • Shuffling a 2D array without using Collections
  • Get last insert id of Postgresql
  • Is it possible to generate a unique numeric value for each row in an iSeries table without looping?
  • C++ - Is destructor called when a vector holds objects?
  • Monotouch crashes with NullReferenceException on non nullable object
  • Access object instance inside an event handler
  • Extract All Possible Paths from Expression-Tree and evaluate them to hold TRUE
  • Magento site down due to mysql error General error: 1030 Got error -1 from storage engine
  • How to get links to open in the native browser in iOS Meteor apps?
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • Alternative To body {overflow:scroll;} That Will Prevent Page Jostling/Wriggling?
  • Play WS (2.2.1): post/put large request
  • Projection media query: browser support and workarounds?
  • HTML download movie download link
  • Warning: Can't call setState (or forceUpdate) on an unmounted component
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • Why joiner is not used after Sequence generator or Update statergy
  • How do I configure my settings file to work with unit tests?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Busy indicator not showing up in wpf window [duplicate]
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • How to Embed XSL into XML
  • How can I use `wmic` in a Windows PE script?