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开发者_StackOverflow(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
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);
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.
You need to construct any new elements in the namespace. Assuming you know the prefix of the namespace you want in the XML sample then do it as follows:
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>";
XElement catalog = XElement.Parse(xml);
XNamespace myP = catalog.GetNamespaceOfPrefix("myPrefix");
catalog.Add(new XElement(myP + "Item", new XAttribute("Name", "foo"), new XAttribute("Mode", "bar")));
精彩评论