web-dev-qa-db-fra.com

Le préfixe "ne peut pas être redéfini de" en <url> dans la même balise d'élément de démarrage

J'essaie de générer l'élément xml suivant en utilisant 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">

Le problème que j'ai, c'est que j'obtiens l'exception:

Le préfixe "ne peut pas être redéfini de" dans la même balise d'élément de démarrage.

Voici mon code c #:

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"));

Comment puis-je réparer cela? J'essaie d'envoyer le xml généré en tant que corps d'un message SOAP et j'ai besoin qu'il soit dans ce format pour le récepteur.

EDIT: J'ai trouvé ma réponse sur une autre question. Contrôle de l'ordre des espaces de noms XML

34
Rainbacon

Vous devez indiquer que l'élément Foo fait partie de l'espace de noms http://schemas.foo.com. Essaye ça:

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")
    );
30
Jose M.

J'obtenais cette erreur lors de la création d'un XDocument. Après beaucoup de recherches sur Google, j'ai trouvé cet article:

http://www.mikesdotnetting.com/Article/111/RSS-Feeds-and-Google-Sitemaps-for-ASP.NET-MVC-with-LINQ-To-XML

Il se trouve juste qu'il y a une explication à mi-chemin dans le document, que j'ai eu la chance de repérer.

Le point clé est que votre code doit laisser le XDocument gérer l'attribut xmlns . Lors de la création d'un XElement, votre premier réflexe serait de définir l'attribut namespace comme tous les autres, en ajoutant un attribut "xmlns" et en le définissant sur une valeur.

Au lieu de cela, vous devez créer une variable XNamespace et utiliser cette variable XNamespace lors de la définition de XElement. Cela ajoutera effectivement un XAttribute à votre élément pour vous.

Lorsque vous ajoutez vous-même un attribut xmlns, vous indiquez à la routine de création XElement de créer un XElement dans aucun espace de noms, puis de modifier l'espace de noms à l'aide de l'attribut xmlns réservé. Vous vous contredisez. L'erreur indique "Vous ne pouvez pas définir l'espace de noms sur vide, puis définissez à nouveau l'espace de noms sur quelque chose d'autre dans la même balise, vous videz."

La fonction ci-dessous illustre cela ...

    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());
    }
4
Steve Hibbert