J'utilise XDocument
pour essayer de supprimer un xmlns=""
attribut sur le premier nœud interne :
<Root xmlns="http://my.namespace">
<Firstelement xmlns="">
<RestOfTheDocument />
</Firstelement>
</Root>
Donc, ce que je veux en conséquence, c'est:
<Root xmlns="http://my.namespace">
<Firstelement>
<RestOfTheDocument />
</Firstelement>
</Root>
doc = XDocument.Load(XmlReader.Create(inStream));
XElement inner = doc.XPathSelectElement("/*/*[1]");
if (inner != null)
{
inner.Attribute("xmlns").Remove();
}
MemoryStream outStream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(outStream);
doc.Save(writer); // <--- Exception occurs here
En essayant d'enregistrer le document, j'obtiens l'exception suivante:
Le préfixe "" ne peut pas être redéfini de "" à " http: //my.namespace " dans la même balise d'élément de démarrage.
Qu'est-ce que cela signifie même et que puis-je faire pour supprimer ce satané xmlns=""
?
xmlns
spécifique soit supprimé, il n'y aura pas d'autres attributs xmlns
dans le document.J'ai essayé d'utiliser du code inspiré des réponses sur cette question :
inner = new XElement(inner.Name.LocalName, inner.Elements());
Lors du débogage, l'attribut xmlns
a disparu mais j'obtiens la même exception.
Je pense que le code ci-dessous est ce que vous voulez. Vous devez mettre chaque élément dans le bon espace de noms, et supprimer tout xmlns=''
attributs pour les éléments affectés. Cette dernière partie est requise car sinon LINQ to XML essaie essentiellement de vous laisser un élément de
<!-- This would be invalid -->
<Firstelement xmlns="" xmlns="http://my.namespace">
Voici le code:
using System;
using System.Xml.Linq;
class Test
{
static void Main()
{
XDocument doc = XDocument.Load("test.xml");
// All elements with an empty namespace...
foreach (var node in doc.Root.Descendants()
.Where(n => n.Name.NamespaceName == ""))
{
// Remove the xmlns='' attribute. Note the use of
// Attributes rather than Attribute, in case the
// attribute doesn't exist (which it might not if we'd
// created the document "manually" instead of loading
// it from a file.)
node.Attributes("xmlns").Remove();
// Inherit the parent namespace instead
node.Name = node.Parent.Name.Namespace + node.Name.LocalName;
}
Console.WriteLine(doc); // Or doc.Save(...)
}
}
Il n'est pas nécessaire de "supprimer" l'attribut xmlns vide. La seule raison pour laquelle l'attribut xmlns vide est ajouté est que l'espace de noms de vos nœuds enfants est vide (= '') et diffère donc de votre nœud racine. L'ajout du même espace de noms à vos enfants résoudra également cet "effet secondaire".
XNamespace xmlns = XNamespace.Get("http://my.namespace");
// wrong
var doc = new XElement(xmlns + "Root", new XElement("Firstelement"));
// gives:
<Root xmlns="http://my.namespace">
<Firstelement xmlns="" />
</Root>
// right
var doc = new XElement(xmlns + "Root", new XElement(xmlns + "Firstelement"));
// gives:
<Root xmlns="http://my.namespace">
<Firstelement />
</Root>