views:

260

answers:

3

I am using VSTS2008 + C# + .Net 3.0. I am using below code to serialize XML, here is my current code and serialized XML file. My purpose is I want to make MyInnerObjectProperties belongs to a special XML namespace (http://foo/2009) and making this namespace as default namespace. Any ideas how to implement this?

Current output:

<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  <MyObjectProperty>
    <MyInnerObjectProperties>
      <MyInnerObjectProperty>
        <ObjectName>Foo Type</ObjectName>
      </MyInnerObjectProperty>
      <MyInnerObjectProperty>
        <ObjectName>Goo Type</ObjectName>
      </MyInnerObjectProperty>
    </MyInnerObjectProperties>
  </MyObjectProperty>
</MyClass>

Current code:

public class MyClass
{
    private MyObject[] _myObjectProperty;

    [XmlElement(IsNullable=false)]
    public MyObject[] MyObjectProperty
    {
        get
        {
            return _myObjectProperty;
        }
        set
        {
            _myObjectProperty = value;
        }
    }
}
public class MyObject
{
    private MyInnerObject[] _myInnerObjectProperty;

    [XmlArrayItemAttribute("MyInnerObjectProperty", typeof(MyInnerObject),  IsNullable=false)]
    public MyInnerObject[] MyInnerObjectProperties
    {
        get
        {
            return _myInnerObjectProperty;
        }
        set
        {
            _myInnerObjectProperty = value;
        }
    }
}

public class MyInnerObject
{
    public string ObjectName;
}

public class Program
{
    static void Main(string[] args)
    {
        XmlSerializer s = new XmlSerializer(typeof(MyClass));
        FileStream fs = new FileStream("foo.xml", FileMode.Create);
        MyClass instance = new MyClass();
        instance.MyObjectProperty = new MyObject[1];
        instance.MyObjectProperty[0] = new MyObject();
        instance.MyObjectProperty[0].MyInnerObjectProperties = new MyInnerObject[2];
        instance.MyObjectProperty[0].MyInnerObjectProperties[0] = new MyInnerObject();
        instance.MyObjectProperty[0].MyInnerObjectProperties[0].ObjectName = "Foo Type";
        instance.MyObjectProperty[0].MyInnerObjectProperties[1] = new MyInnerObject();
        instance.MyObjectProperty[0].MyInnerObjectProperties[1].ObjectName = "Goo Type";

        s.Serialize(fs, instance);

        return;
    }
}
+1  A: 

You need to create an XmlSerializerNamespaces object, and add your needed namespaces to it.

The XmlSerializerNamespaces object contains the XML namespaces and prefixes that the XmlSerializer uses to generate qualified names in an XML-document instance.

In your c# code:

XmlSerializerNamespaces myNameSpaces = new XmlSerializerNamespaces();
myNameSpaces.Add("MyInnerObject", "http://foo/2009");

Then, add an attribute to your class, like this:

public class MyInnerObject
{
[XmlElement(Namespace = "http://foo/2009")]

More info at:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializernamespaces.aspx

Robert Harvey
Thanks Robert. My purpose is not adding everything of class MyClass into a unified namespace, but to add just MyInnerObjectProperties elements into namespace "http://foo/2009". I think your solution will add all elements from class MyClass into "http://foo/2009", correct? Any ideas to my issue?
George2
You don't have to use it for the whole class. You can pick and choose the elements and attributes you want. See http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializernamespaces.aspx
Robert Harvey
I edited my answer to more closely align with your question.
Robert Harvey
Working, cool! Thanks!
George2
+1  A: 

How about this:

[XmlArrayItemAttribute( Namespace = "http://foo.com/2009" /* other attr. params. */ )]
public MyInnerObject[] MyInnerObjectProperties
{
    get { ... }
    set { ... }
}
azheglov
Working, cool! Thanks!
George2
+2  A: 

Try

public class MyObject
{
    [XmlArrayItemAttribute("MyInnerObjectProperty", typeof (MyInnerObject),
        IsNullable = false)]
    [XmlArray(Namespace = "http://foo.com/2009")]
    public MyInnerObject[] MyInnerObjectProperties { get; set; }
}

for me, this produces:

<?xml version="1.0" encoding="utf-8"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <MyObjectProperty>
        <MyInnerObjectProperties xmlns="http://foo.com/2009"&gt;
            <MyInnerObjectProperty>
                <ObjectName>Foo Type</ObjectName>
            </MyInnerObjectProperty>
            <MyInnerObjectProperty>
                <ObjectName>Goo Type</ObjectName>
            </MyInnerObjectProperty>
        </MyInnerObjectProperties>
    </MyObjectProperty>
</MyClass>
John Saunders
+1 this is what i was thinking as well..
Stan R.