Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The prefix " cannot be redefined from " to <url> within the same start element tag

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

like image 781
Rainbacon Avatar asked May 16 '14 15:05

Rainbacon


2 Answers

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());
    }
like image 43
Steve Hibbert Avatar answered Nov 20 '22 04:11

Steve Hibbert


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")
    );
like image 162
Jose M. Avatar answered Nov 20 '22 03:11

Jose M.