2

I'm having trouble getting my top-level element to look exactly like this using the XmlSerializer (and C# attributes):

<rootObject xmlns="http://www.example.com/xmlschemas/nonStandardSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.example.com/xmlschemas/nonStandardSchema1.xsd">
    <otherSerializedObjects />
</rootObject>

Currently, the closest I've gotten is this:

<rootObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    d1p1:schemaLocation="http://www.example.com/xmlschemas/nonStandardSchema1.xsd" 
    xmlns:d1p1="xsi" 
    xmlns="http://www.example.com/xmlschemas/nonStandardSchema">
    <otherSerializedObjects />
</rootObject>

C#

[XmlRoot("rootObject", Namespace = "http://www.example.com/xmlschemas/nonStandardSchema")]
public class RootObject
{
    [XmlAttribute("schemaLocation", Namespace = "xsi")]
    public string SchemaLocation { get; set; }

    [XmlElement("Image")]
    public Object[] OtherSerializedObjects { get; set; }

    public RootObject()
    {
        OtherSerializedObjects = new Object[]{};
    }
}   

public class Program
{
    static void Main(string[] args)
    {
        var rootObject = new RootObject
        {
            SchemaLocation = "http://www.example.com/xmlschemas/nonStandardSchema1.xsd",
            OtherSerializedObjects = new object[]{}
        };

        var serializer = new XmlSerializer(typeof(RootObject));
        var stringWriter = new StringWriter();
        serializer.Serialize(stringWriter, rootObject);
        Console.WriteLine(stringWriter.ToString()); 
    }
}

Any ideas?

2
  • 1
    What have you tried? How close have you gotten? What specifically does "having trouble" mean? Commented Jul 13, 2015 at 23:22
  • Possibly a duplicate of stackoverflow.com/questions/27530334/… Commented Jul 13, 2015 at 23:43

2 Answers 2

2

Firstly, the [XmlAttribute(Namespace=X)] attribute on your schemaLocation field/property needs to have the full namespace for the value of X, not the local namespace shortcut. Incidentally, this can be a property rather than a field. Using a field for this purpose wastes memory.

Secondly, to eliminate the standard xmlns:xsd="http://www.w3.org/2001/XMLSchema", use an XmlSerializer.Serialize overload where you pass in an XmlSerializerNamespaces with just the namespaces you want.

Thus:

[XmlRoot("rootObject", Namespace = "http://www.example.com/xmlschemas/nonStandardSchema")]
public class RootObject
{
    public static XmlSerializerNamespaces GetAdditionalNamespaces()
    {
        XmlSerializerNamespaces xsNS = new XmlSerializerNamespaces();


        xsNS.Add("", "http://www.example.com/xmlschemas/nonStandardSchema");
        xsNS.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

        return xsNS;
    }

    [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string XSDSchemaLocation
    {
        get
        {
            return "http://www.example.com/xmlschemas/nonStandardSchema1.xsd";
        }
        set
        {
            // Do nothing - fake property.
        }
    }

    [XmlElement("Image")]
    public Object[] OtherSerializedObjects { get; set; }

    public RootObject()
    {
        OtherSerializedObjects = new Object[]{};
    }
}   

And then use it like:

        var rootObject = new RootObject
        {
            OtherSerializedObjects = new object[]{}
        };

        var serializer = new XmlSerializer(typeof(RootObject));
        var stringWriter = new StringWriter();
        var ns = RootObject.GetAdditionalNamespaces();

        var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " }; // For cosmetic purposes.
        using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
        {
            serializer.Serialize(xmlWriter, rootObject, ns);
        }

        Console.WriteLine(stringWriter.ToString()); 

Example fiddle.

Sign up to request clarification or add additional context in comments.

1 Comment

(Looking back at older questions) - this was the right answer, it worked as I needed. Thanks!
0

Namespace needs to be the entire namespace, not the shortened version.

[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]

In my testing it automatically used xsi.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.