I'm trying to generate the following xml element using C#.
<Foo xmlns="http://schemas.foo.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.foo.com
http://schemas.foo.com/Current/xsd/Foo.xsd">
The problem that I'm having is that I get the exception:
The prefix " cannot be redefined from " to within the same start element tag.
This is my c# code:
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
XElement foo = new XElement("Foo", new XAttribute("xmlns", "http://schemas.foo.com"),
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(xsi + "schemaLocation", "http://schemas.foo.com http://schemas.foo.com/Current/xsd/Foo.xsd"));
How can I fix this? I'm trying to send the generated xml as the body of a SOAP message and I need it to be in this format for the receiver.
EDIT: I found my answer on another question. Controlling the order of XML namepaces
I was getting this error when creating an XDocument. After a lot of googling I found this article:
http://www.mikesdotnetting.com/Article/111/RSS-Feeds-and-Google-Sitemaps-for-ASP.NET-MVC-with-LINQ-To-XML
There just happens to be an explanation part way through the doc, that I was lucky enough to spot.
The key point is that your code should let the XDocument handle the xmlns attribute. When creating an XElement, your first instinct would be to set the namespace attribute like all the rest, by adding an attribute "xmlns" and setting it to a value.
Instead, you should create an XNamespace variable, and use that XNamespace variable when defining the XElement. This will effectively add an XAttribute to your element for you.
When you add an xmlns attribute yourself, you are telling the XElement creation routine to create an XElement in no namespace, and then to change the namespace using the reserved xmlns attribute. You are contradicting yourself. The error says "You cannot set the namespace to empty, and then set the namespace again to something else in the same tag, you numpty."
The function below illustrates this...
private static void Test_Namespace_Error(bool doAnError)
{
XDocument xDoc = new XDocument();
string ns = "http://mynamespace.com";
XElement xEl = null;
if (doAnError)
{
// WRONG: This creates an element with no namespace and then changes the namespace
xEl = new XElement("tagName", new XAttribute("xmlns", ns));
}
else
{
// RIGHT: This creates an element in a namespace, and implicitly adds an xmlns tag
XNamespace xNs = ns;
xEl = new XElement(xNs + "tagName");
}
xDoc.Add(xEl);
Console.WriteLine(xDoc.ToString());
}
You need to indicate that the element Foo
is part of the namespace http://schemas.foo.com
. Try this:
XNamespace xNamespace = "http://schemas.foo.com";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
XElement foo = new XElement(
xNamespace + "Foo",
new XAttribute("xmlns", "http://schemas.foo.com"),
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(xsi + "schemaLocation", "http://schemas.foo.com http://schemas.foo.com/Current/xsd/Foo.xsd")
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With