2012-04-06 11 views
8

Estoy usando XmlWriterSettings para escribir Xml en el archivo. Tengo elementos con solo atributos, sin hijos. Los quiero a la salida como:Indique XmlWriterSettings para usar etiquetas de cierre automático

<element a="1" /> 

en lugar de

<element a="1"></element> 

¿Puedo hacerlo con XmlWriterSettings?

EDIT:

código es el siguiente:

private void Mission_Save(string fileName) 
    { 
     StreamWriter streamWriter = new StreamWriter(fileName, false); 
     streamWriter.Write(Mission_ToXml()); 
     streamWriter.Close(); 
     streamWriter.Dispose(); 

     _MissionFilePath = fileName; 
    } 

private string Mission_ToXml() 
    { 
     XmlDocument xDoc; 
     XmlElement root; 
     XmlAttribute xAtt; 

     xDoc = new XmlDocument(); 

     foreach (string item in _MissionCommentsBefore) 
      xDoc.AppendChild(xDoc.CreateComment(item)); 

     root = xDoc.CreateElement("mission_data"); 
     xAtt = xDoc.CreateAttribute("version"); 
     xAtt.Value = "1.61"; 
     root.Attributes.Append(xAtt); 
     xDoc.AppendChild(root); 

     //Out the xml's! 
     foreach (TreeNode node in _FM_tve_Mission.Nodes) 
      Mission_ToXml_private_RecursivelyOut(root, xDoc, node); 

     foreach (string item in _MissionCommentsAfter) 
      xDoc.AppendChild(xDoc.CreateComment(item)); 


     //Make this look good 
     StringBuilder sb = new StringBuilder(); 
     XmlWriterSettings settings = new XmlWriterSettings(); 

     settings.Indent = true; 
     settings.IndentChars = " "; 
     settings.NewLineChars = "\r\n"; 
     settings.NewLineHandling = NewLineHandling.Replace; 
     settings.OmitXmlDeclaration = true; 
     using (XmlWriter writer = XmlWriter.Create(sb, settings)) 
     { 
      xDoc.Save(writer); 
     } 

     return sb.ToString(); 
    } 

private void Mission_ToXml_private_RecursivelyOut(XmlNode root, XmlDocument xDoc, TreeNode tNode) 
    { 
     root.AppendChild(((MissionNode)tNode.Tag).ToXml(xDoc)); 
     foreach (TreeNode node in tNode.Nodes) 
      Mission_ToXml_private_RecursivelyOut(root, xDoc, node); 
    } 

aquí _FM_tve_Mission es un control TreeView que tiene nodos, cada uno de los nodos tiene una etiqueta de MissionNode clase, que tiene método un ToXml que devuelve XmlNode que contiene este MissionNode convierte a XML

+0

¿cuál es su código? Un [XmlWriter sin configuraciones específicas] (http://ideone.com/g158S) las escribe de la manera que desee –

Respuesta

8

Usted no necesita ninguna configuración especial para ello:

XmlWriter output = XmlWriter.Create(filepath); 
output.writeStartElement("element"); 
output.writeAttributeString("a", "1"); 
output.writeEndElement(); 

que le dará una salida de <element a="1" /> (Sólo probado en una aplicación que estoy trabajando en la escritura de XML para)

Básicamente si no añadir ningún dato antes de escribir el elemento final que se acaba de cerrar fuera para usted .

que también tienen las siguientes XmlWriterSettings puede ser uno de estos si isnt de trabajo por defecto:

XML
XmlWriterSettings wSettings = new XmlWriterSettings(); 
wSettings.Indent = true; 
wSettings.ConformanceLevel = ConformanceLevel.Fragment; 
wSettings.OmitXmlDeclaration = true; 
XmlWriter output = XmlWriter.Create(filePathXml, wSettings); 
+0

No, no, no, no comprende. Tengo un XML muy complejo, en realidad es un editor de misión para un juego que almacena escenarios (conjunto de scripts y eventos y demás) en formato xml, por lo que se genera dinámicamente y me gustaría usar xmlwriter para generarlo solo con XmlWriter. Write (myXml) – Istrebitel

+0

XmlWriter solo tiene un método estático 'Create'. No puede llamar a 'XmlWriter.Write()' porque no existe. Debe escribir cada nodo con el nombre y los atributos individualmente. De la explicación que dijiste esto es exactamente lo que quieres. No se puede pasar mágicamente datos a la xmlwriter y esperar salida. Tienes que decirle qué elementos y atributos mostrar. – jzworkman

+0

Ah, lo siento, estaba equivocado, se llama Guardar no escribir ...Lo que quise decir es usar el objeto del tipo XmlDocument's method Save (pasando el objeto XmlWriter), agregué código al OP – Istrebitel

1

procesamiento de un archivo externo, que escribió la siguiente clase para deshacerse de que no esté vacía cerrada Elementos. Mi XML ahora tiene etiquetas de cierre automático.

using System.Linq; 
using System.Xml.Linq; 

namespace XmlBeautifier 
{ 
    public class XmlBeautifier 
    { 
     public static string BeautifyXml(string outerXml) 
     { 
      var _elementOriginalXml = XElement.Parse(outerXml); 
      var _beautifiedXml = CloneElement(_elementOriginalXml); 
      return _beautifiedXml.ToString(); 
     } 

     public static XElement CloneElement(XElement element) 
     { 
      // http://blogs.msdn.com/b/ericwhite/archive/2009/07/08/empty-elements-and-self-closing-tags.aspx 
      return new XElement(element.Name, 
       element.Attributes(), 
       element.Nodes().Select(n => 
       { 
        XElement e = n as XElement; 
        if (e != null) 
         return CloneElement(e); 
        return n; 
       }) 
      ); 
     } 

    } 
} 
0

Con expresiones regulares y el método recursivo, es tarea fácil:

using System.Xml.Linq; 
    public static class Xml 
    { 
     /// <summary> 
     /// Recursive method to shorten all xml end tags starting from a given element, and running through all sub elements 
     /// </summary> 
     /// <param name="elem">Starting point element</param> 
     public static void ToShortEndTags(this XElement elem) 
     { 
      if (elem == null) return; 

      if (elem.HasElements) 
      { 
       foreach (var item in elem.Elements()) ToShortEndTags(item); 
       return; 
      } 

      var reduced = Regex.Replace(elem.ToString(), ">[\\s\\n\\r]*</\\w+>", "/>"); 

      elem.ReplaceWith(XElement.Parse(reduced)); 
     } 
    } 

Y para usarlo Escribe algo como esto:

var path = @"C:\SomeFile.xml"; 
    var xdoc = XDocument.Load(path).Root.ToShortEndTags(); 

xdoc es ahora, una instancia de XDocument cargados desde una ruta determinada, pero todos sus elementos elegibles (sin contenido) Etiquetas de finalización completa ahora son Corto ened

Cuestiones relacionadas