Pregunta

Estoy usando esto para mi código, genera perfectamente el archivo XML, pero agrega un signo '=' después del nombre del elemento a pesar de que solo uno de mis elementos tiene un atributo.

Supongo que podría hacer algo como

if(reader.Getattribute != "")
// I made that up on the spot, I'm not sure if that would really work
{
      Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
}

else
{
      Console.WriteLine("<{0}>", reader.Name);
}

¿Pero hay una forma más limpia de codificar eso?

Mi código (sin solución)

using System;
using System.Xml;
using System.IO;
using System.Text;

public class MainClass
{
    private static void Main()
    {
        XmlWriterSettings settings = new XmlWriterSettings();

        settings.Indent = true;


        XmlWriter w = XmlWriter.Create(@"Path\test.xml", settings);



        w.WriteStartDocument();
        w.WriteStartElement("classes");

        w.WriteStartElement("class");
        w.WriteAttributeString("name", "EE 999");
        w.WriteElementString("Class_Name", "Programming");
        w.WriteElementString("Teacher", "James");
        w.WriteElementString("Room_Number", "333");
        w.WriteElementString("ID", "2324324");
        w.WriteEndElement();




        w.WriteEndDocument();
        w.Flush();
        w.Close();




        XmlReader reader = XmlReader.Create(@"Path\test.xml");

        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
                    break;
                case XmlNodeType.Text:
                    Console.WriteLine(reader.Value);
                    break;
                case XmlNodeType.CDATA:
                    Console.WriteLine("<[CDATA[{0}]>", reader.Value);
                    break;
                case XmlNodeType.ProcessingInstruction:
                    Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    Console.WriteLine("<!--{0}-->", reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                    Console.WriteLine("<?xml version='1.0'?>");
                    break;
                case XmlNodeType.Document:
                    break;
                case XmlNodeType.DocumentType:
                    Console.WriteLine("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
                    break;
                case XmlNodeType.EntityReference:
                    Console.WriteLine(reader.Name);
                    break;
                case XmlNodeType.EndElement:
                    Console.WriteLine("</{0}>", reader.Name);
                    break;
            }
        }
    }
}

Producción

<?xml version='1.0'?>
<classes = >
<class = EE 999>
<Class_Name = >
Programming
</Class_Name>
<Teacher = >
James
</Teacher>
<Room_Number = >
333
</Room_Number>
<ID = >
2324324
</ID>
</class>
</classes>
¿Fue útil?

Solución

Porque esta línea

case XmlNodeType.Element:
       Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
       break;

Siempre escribe el '=' sin verificar.

Una solución difícil:

case XmlNodeType.Element:
       Console.WriteLine("<{0}", reader.Name);
       if (reader.HasAttributes)
          // Write out attributes
       Console.WriteLine(">");
       break;

Pero, ¿por qué estás usando el XMLReader? Es engorroso y solo útil cuando se trata de grandes transmisiones XML.

Si sus conjuntos de datos no son >> 10 MB, eche un vistazo a xDocument o XMLDocument

El Writer XML en su ejemplo puede ser reemplazado por (aprox.

 // using System.Xml.Linq;

        var root = new XElement("classes",
            new XElement("class", new XAttribute("name", "EE 999"),
                new XElement("Class_Name", "Programming"),
                new XElement("Teacher", "James")
                ));

        root.Save(@"Path\test.xml");

     var doc = XDocument.Load(@"Path\test.xml");
     // doc is now an in-memory tree of XElement objects 
     // that you can navigate and query

Y aquí esta una introducción

Otros consejos

No sé exactamente lo que está tratando de lograr, pero personalmente crearía una clase .NET que represente su elemento de clase con propiedades que identifican los sub elementos y luego use System.xml.Serialization.xmlSerializer para escribirlo o leerlo desde un archivo.

Aquí hay un ejemplo:

using System.Xml.Serialization;

public class MyClasses : List<MyClass>{}    

public class MyClass{
 public String Teacher{ get; set; }
}

void main(){
  MyClasses classList = new MyClasses();

  MyClass c = new MyClass();
  c.Teacher = "James";

  classList.Add(c);

  XmlSerializer serializer = new XmlSerializer(classList.GetType());
  serializer.Serialize(/*Put your stream here*/);
}

Y, después de dejar la configuración de su transmisión como un ejercicio para el lector, BLAMO, ha terminado de producir una representación XML de su objeto a algún flujo. La transmisión podría ser un archivo, cadena, lo que sea. Perdón por la desagradable C# (si es desagradable) uso VB.NET todos los días para que la sintaxis y las palabras clave puedan estar un poco apagadas.

Actualizar
Agregué algún código para mostrar cómo serializar una colección de las clases. Si los nodos no están saliendo correctamente, hay atributos que puede agregar a las propiedades de su clase, solo haga un Google rápido para ellos.

Actualizar nuevamente
Lo siento, es difícil de explicar cuando estamos usando la misma palabra para significar dos cosas diferentes. Digamos que estás tratando de representar un cubo de ladrillos. Escribirías una clase C# llamada Brick y una clase C# llamada Bucket que heredó de List<Brick> su Brick tendría una propiedad llamada Color. Luego harías todos tus ladrillos con diferentes colores y llenarías el cubo con tus ladrillos. Entonces pasarías tu cubo al serializador y te daría algo como:

<Bucket>    
  <Brick>  
    <Color>    
      blue     
    </Color>  
  </Brick>   
</Bucket> 

El serializador crea el XML para usted a partir de las definiciones de sus clases para que no tenga que preocuparse por los detalles. Puedes leer más sobre eso aquí y aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top