Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XElement add prefix only

I have an XML file like:

<myPrefix:Catalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 xmlns:sys="clr-namespace:System;assembly=mscorlib" 
 xmlns:myPrefix="clr-namespace:........">

  <myPrefix:Item Name="Item1" Mode="All" />
  <myPrefix:Item Name="Item2" Mode="Single" />

</myPrefix:Catalog>

With C# I create a new Item like:

XContainer container = XElement.Parse(xml);
XElement xmlTree = 
   new XElement("Item",
      new XAttribute("Name", item.Name),
      new XAttribute("Mode", item.Mode));

As you can see I don't add the "myPrefix" prefix. Can anyone tell me how i can do that? I don't want to declarde the xmlns again. Thanks, Peter

like image 910
Peter Avatar asked May 12 '11 07:05

Peter


2 Answers

    XElement container = XElement.Parse(xml);
    XNamespace myPrefix = container.GetNamespaceOfPrefix("myPrefix");

    XElement xmlTree = new XElement(myPrefix + "Item",     
                            new XAttribute("Name", item.Name), 
                            new XAttribute("Mode", item.Mode));

    container.Add(xmlTree);
like image 156
Tom Brothers Avatar answered Sep 19 '22 07:09

Tom Brothers


Edit 1:
If you add the namespace attribute aswell to the element this will force it to add the prefix. But you still end up with the xmlns attribute in the node. To remove it you'll probably, as Jeff says, need to utilize XmlWriter.

Edit 2:
To get the EXACT XML you want you need to create the root element aswell:

Edit 3:
OK. I found a way to get what you want without XmlWriter:

var xml = "<myPrefix:Catalog xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:sys=\"clr-namespace:System;assembly=mscorlib\" xmlns:myPrefix=\"clr-namespace:........\"><myPrefix:Item Name=\"Item1\" Mode=\"All\" /></myPrefix:Catalog>";

XNamespace presentation = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XNamespace xaml = "http://schemas.microsoft.com/winfx/2006/xaml";
XNamespace mscorlib = "clr-namespace:System;assembly=mscorlib";
XNamespace myPrefix = "clr-namespace:.......";

XElement container = XElement.Parse(xml);

var xmlTree = new XElement("Item",
               new XAttribute("Name", "Item2"),
               new XAttribute("Mode", "Single"));

container.Add(xmlTree);

foreach (var el in container.DescendantsAndSelf())
{
  el.Name = myPrefix.GetName(el.Name.LocalName);
  var atList = el.Attributes().ToList();
  el.Attributes().Remove();
  foreach (var at in atList)
  {
    if (el.Name.LocalName == "Catalog" && at.Name.LocalName != "xmlns")
      continue;
    el.Add(new XAttribute(at.Name.LocalName, at.Value));
  }
}

container.Add(new XAttribute(XNamespace.Xmlns + "x", xaml));
container.Add(new XAttribute(XNamespace.Xmlns + "sys", mscorlib));
container.Add(new XAttribute(XNamespace.Xmlns + "myPrefix", myPrefix));

Edit 4:
Apparently there was an easier way... a LOT easier... see the other answers.

like image 40
Sani Singh Huttunen Avatar answered Sep 19 '22 07:09

Sani Singh Huttunen