Creating XML with namespaces and schemas from an XElement
-
22-07-2019 - |
Question
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...
Solution
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.
OTHER TIPS
Thanks to David B - I'm not quite sure I understand all this but this code gets me what I need...
public XElement ToXElement()
{
const string ns = "http://www.someurl.com/ns/myroot";
const string w3 = "http://wwww.w3.org/2001/XMLSchema-instance";
const string schema_location = "http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd";
XNamespace xnsp = ns;
XNamespace w3nsp = w3;
XElement xe = new XElement(xnsp + "myroot",
new XAttribute(XNamespace.Xmlns + "xsi", w3),
new XAttribute(w3nsp + "schemaLocation", schema_location),
new XElement(xnsp + "sometag", "somecontent")
);
return xe;
}
It appears that concatenating a namespace plus a string eg
w3nsp + "schemaLocation"gives an attribute called
xsi:schemaLocationin the resulting XML, which is what I need.