Creating XML with namespaces and schemas from an XElement

SAL picture SAL · Dec 2, 2008 · Viewed 8.9k times · Source

A longwinded question - please bear with me!

I want to programatically create an XML document with namespaces and schemas. Something like

<myroot 
    xmlns="http://www.someurl.com/ns/myroot" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd">

    <sometag>somecontent</sometag>

</myroot>

I'm using the rather splendid new LINQ stuff (which is new to me), and was hoping to do the above using an XElement.

I've got a ToXElement() method on my object:

  public XElement ToXElement()
  {
     XNamespace xnsp = "http://www.someurl.com/ns/myroot";

     XElement xe = new XElement(
        xnsp + "myroot",
           new XElement(xnsp + "sometag", "somecontent")
        );

     return xe;
  }

which gives me the namespace correctly, thus:

<myroot xmlns="http://www.someurl.com/ns/myroot">
   <sometag>somecontent</sometag>
</myroot>

My question: how can I add the schema xmlns:xsi and xsi:schemaLocation attributes?

(BTW I can't use simple XAtttributes as I get an error for using the colon ":" in an attribute name...)

Or do I need to use an XDocument or some other LINQ class?

Thanks...

Answer

Amy B picture Amy B · Dec 2, 2008

From this article, it looks like you new up more than one XNamespace, add an attribute in the root, and then go to town with both XNamespaces.

// The http://www.adventure-works.com namespace is forced to be the default namespace.
XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
    new XAttribute("xmlns", "http://www.adventure-works.com"),
///////////  I say, check out this line.
    new XAttribute(XNamespace.Xmlns + "fc", "www.fourthcoffee.com"),
///////////
    new XElement(fc + "Child",
        new XElement(aw + "DifferentChild", "other content")
    ),
    new XElement(aw + "Child2", "c2 content"),
    new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Here's a forum post showing how to do the schemalocation.