Search code examples
c#.netxmlserializer

XMLSerialization - Custom root attributes


I am working on a project to serialize XML and set it to a web service. The root element is highly customized, and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<eAction xmlns="http://www.action.org/standards/PC_Surety/action1/xml/" xmlns:cation="http://www.caction.org/standards/pc_go/xml/" xmlns:acme="http://www.ACME.org/standards/ACME1/xml/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

The root has a couple of different namespaces, and the xsd attribute is not present.

I've been trying to work out how to add the extra namespace attributes and if, perhaps, serialization is not the way to go with this.

So far, I have a test program with simple set of classes to serialize:

private void button1_Click(object sender, EventArgs e)
{
  XmlSerializer xmlSerialize = new XmlSerializer(typeof(eAction));
  TextWriter txtWriter = new StreamWriter(@"c:\actionout.xml");
  eAction eActionItem = new eAction();

  xmlSerialize.Serialize(txtWriter, eActionItem);
}

[XmlRoot(ElementName="eAction")]
public class eAction
{
  public string Name = string.Empty;
  public string Street1 = string.Empty;
  public string Street2 = string.Empty;
  public string City = string.Empty;
  public string State = string.Empty;
  public string PostalCode = string.Empty;

  public OtherInformation OtherInformation = new OtherInformation();
}

public class OtherInformation
{
  public string DateOfBirth = string.Empty;
  public string SSN = string.Empty;
}

Running this creates this xml:

<?xml version="1.0" encoding="utf-8"?>
<eAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name />
  <Street1 />
  <Street2 />
  <City />
  <State />
  <PostalCode />
  <OtherInformation>
    <DateOfBirth />
    <SSN />
  </OtherInformation>
</eAction>

Is there a good way to add the attributes that I need?

Edit: The accepted answer solve the problem. One more question - I also have to add:

xsi:schemaLocation="http://www.action.org/standards/PC_Surety/action1/xml/ standardsFile.xsd"

Can this be added as a namespace, but with xsi substituted for xmlns, or is there a different way to add this attribute?


Solution

  • I think this might do what you need. You were RIGHT there, :) .

    Your class:

    [XmlRoot(ElementName = "eAction", Namespace = "http://www.action.org/standards/PC_Surety/action1/xml/")]
    public class eAction
    {
        [XmlAttribute(Namespace = XmlSchema.InstanceNamespace)]
        public string schemaLocation = "http://www.action.org/standards/PC_Surety/action1/xml/standardsFile.xsd";
        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
    
        public eAction()
        {
            xmlns.Add("cation", "http://www.caction.org/standards/pc_go/xml/");
            xmlns.Add("acme", "http://www.ACME.org/standards/ACME1/xml/");
            xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        }
    
        public string Name = string.Empty;
        public string Street1 = string.Empty;
        public string Street2 = string.Empty;
        public string City = string.Empty;
        public string State = string.Empty;
        public string PostalCode = string.Empty;
    
        public OtherInformation OtherInformation = new OtherInformation();
    }
    
    public class OtherInformation
    {
        public string DateOfBirth = string.Empty;
        public string SSN = string.Empty;
    }
    

    Use example:

            private static void button1_click()
        {
            var xmlSerializer = new XmlSerializer(typeof(eAction));
            using (var txtWriter = new StreamWriter(@"C:\temp\actionout.xml"))
            {
                var eActionItem = new eAction();
                xmlSerializer.Serialize(txtWriter, eActionItem);
            }
        }