2011-05-12 14 views
7

tengo un archivo XML como:XElement añadir el prefijo única

<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> 

con C# se crea un nuevo artículo como:

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

Como se puede ver no añado el "myPrefix" prefijo. ¿Alguien puede decirme cómo puedo hacer eso? No quiero declarar los xmlns nuevamente. Gracias, Peter

Respuesta

3

Edición 1:
Si se agrega el espacio de nombres de atributo al elemento aswell esto obligará a añadir el prefijo. Pero todavía terminas con el atributo xmlns en el nodo. Para eliminarlo, probablemente, como dice Jeff, necesite utilizar XmlWriter.

Edición 2:
Para obtener el XML exacto que desea que necesita para crear el elemento raíz aswell:

Datos 3:
OK. He encontrado una manera de conseguir lo que quiere sin 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)); 

Editar 4:
Parece que había una manera más fácil ... ... mucho más fácil ver las otras respuestas.

+0

Gracias por su respuesta, pero no va a funcionar. El resultado es como: Peter

+1

@Peter: Aparecerá de esa manera si el elemento es el raíz. No es la raíz, entonces será prefijada si el espacio de nombres es declarado en un ancestro. –

+0

@Jeff ¿Y cómo puedo hacer que funcione de la manera correcta? – Peter

7
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); 
+0

+1 ¡Agradable! Sabía que tenía que haber una manera más fácil. –

2

Necesita construir cualquier elemento nuevo en el espacio de nombres. Suponiendo que conoce el prefijo del espacio de nombres que desee en el XML de ejemplo y luego hacerlo de la siguiente manera:

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

+1 ¡Agradable!Sabía que tenía que haber una manera más fácil. –

+0

Muchas gracias por esta buena solución. – Peter

Cuestiones relacionadas