XmlSerializer in .NET with XmlSchemaForm.Unqualified

11.1k Views Asked by At

Given the following piece of code:

using System;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    [XmlType(Namespace = "http://www.test.com")]
    public class Element
    {
        [XmlElement]
        public int X;
    }

    [XmlRoot(Namespace = "http://www.test.com")]
    public class Root
    {
        [XmlElement(Form = XmlSchemaForm.Unqualified)]
        public Element Element;
    }

    public static class Program
    {
        public static void Main(string[] args)
        {
            var root = new Root { Element = new Element { X = 1 } };
            var xmlSerializer = new XmlSerializer(typeof(Root));
            xmlSerializer.Serialize(Console.Out, root);
        }
    }
}

the output is:

<?xml version="1.0" encoding="ibm852"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com">
  <Element xmlns="">
    <X xmlns="http://www.test.com">1</X>
  </Element>
</Root>

The question is why does setting the Form property to XmlSchemaForm.Unqualified cause the Element element's namespace being set to "" even if it has the XmlTypeAttribute attribute with the same namespace as the Root element?

This kind of code (the XmlSchemaForm.Unqualified part) is generated by the WSCF.blue tool and it's messing up with the namespaces.

1

There are 1 best solutions below

0
Ivan Krivyakov On

You can override namespace specified in the element type. E.g. you can have

[XmlElement(Namespace="http://foo.com")]
public Element Element;

And the output would be

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com">
  <Element xmlns="http://foo.com">
    <X xmlns="http://www.test.com">1</X>
  </Element>
</Root>

Microsoft's implementation of Form = XmlSchemaForm.Unqualified appears to be exactly equivalent to setting Namespace to "". In particular, it cannot be used if you explicitly specified any other namespace (MSDN reference). If you do, you will get this exception:

Unhandled Exception: System.InvalidOperationException: There was an error reflecting type 'XmlSerializationTest.Root'. ---> System.InvalidOperationException: There was an error reflecting field 'Element'. ---> System.InvalidOperationException: The Form property may not be 'Unqualified' when an explicit Namespace property is present.