Pregunta

Estoy trabajando en un conjunto de clases que se utilizarán para serializar en XML.El XML no lo controlo yo y está bastante bien organizado.Desafortunadamente, hay varios conjuntos de nodos anidados, el propósito de algunos de ellos es simplemente contener una colección de sus hijos.Según mi conocimiento actual de serialización XML, esos nodos requieren otra clase.

¿Hay alguna manera de hacer que una clase se serialice en un conjunto de nodos XML en lugar de solo uno?Como siento que estoy siendo tan claro como el barro, digamos que tenemos el xml:

<root>
    <users>
        <user id="">
            <firstname />
            <lastname />
            ...
        </user>
        <user id="">
            <firstname />
            <lastname />
            ...
        </user>
    </users>
    <groups>
        <group id="" groupname="">
            <userid />
            <userid />
        </group>
        <group id="" groupname="">
            <userid />
            <userid />
        </group>
    </groups>
</root>

Lo ideal sería 3 clases.Una clase root con colecciones de user y group objetos.Sin embargo, lo mejor que puedo entender es que necesito una clase para root, users, user, groups y group, dónde users y groups contienen sólo colecciones de user y group respectivamente, y root contiene una users, y groups objeto.

¿Alguien por ahí que sepa mejor que yo?(no mientas, sé que las hay).

¿Fue útil?

Solución

¿No estás usando el XmlSerializador?Es bastante bueno y hace que hacer cosas como esta sea realmente fácil (¡lo uso bastante!).

Simplemente puede decorar las propiedades de su clase con algunos atributos y el resto estará hecho por usted.

¿Ha considerado utilizar XmlSerializer o hay alguna razón particular por la que no?

Aquí hay un fragmento de código de todo el trabajo necesario para serializar lo anterior (en ambos sentidos):

[XmlArray("users"),
XmlArrayItem("user")]
public List<User> Users
{
    get { return _users; }
}

Otros consejos

Sólo necesitaría tener los Usuarios definidos como una matriz de objetos de Usuario.XmlSerializer lo renderizará adecuadamente.

Vea este enlace para ver un ejemplo:http://www.informit.com/articles/article.aspx?p=23105&seqNum=4

Además, recomendaría usar Visual Studio para generar un XSD y usar la utilidad de línea de comandos XSD.EXE para mostrarle la jerarquía de clases, según http://quickstart.developerfusion.co.uk/quickstart/howto/doc/xmlserialization/XSDToCls.aspx

Escribí esta clase en el pasado para hacer lo que creo que es similar a lo que estás tratando de hacer.Utilizaría métodos de esta clase en objetos que desee serializar en XML.Por ejemplo, dado un empleado...

utilizando Utilidades;usando System.Xml.Serialization;

Xmlroot ("empleado")] empleado de clase pública {private string name = "steve";

 [XmlElement("Name")]
 public string Name { get { return name; } set{ name = value; } }

 public static void Main(String[] args)
 {
      Employee e = new Employee();
      XmlObjectSerializer.Save("c:\steve.xml", e);
 }

}

este código debería generar:

<Employee>
  <Name>Steve</Name>
</Employee>

El tipo de objeto (Empleado) debe ser serializable.Pruebe [Serializable (verdadero)].Tengo una versión mejor de este código en alguna parte, estaba aprendiendo cuando lo escribí.De todos modos, consulte el código a continuación.Lo estoy usando en algún proyecto, así que definitivamente funciona.

using System;
using System.IO;
using System.Xml.Serialization;

namespace Utilities
{
    /// <summary>
    /// Opens and Saves objects to Xml
    /// </summary>
    /// <projectIndependent>True</projectIndependent>
    public static class XmlObjectSerializer
    {
        /// <summary>
        /// Serializes and saves data contained in obj to an XML file located at filePath <para></para>        
        /// </summary>
        /// <param name="filePath">The file path to save to</param>
        /// <param name="obj">The object to save</param>
        /// <exception cref="System.IO.IOException">Thrown if an error occurs while saving the object. See inner exception for details</exception>
        public static void Save(String filePath, Object obj)
        {
            // allows access to the file
            StreamWriter oWriter =  null;

            try
            {
                // Open a stream to the file path
                 oWriter = new StreamWriter(filePath);

                // Create a serializer for the object's type
                XmlSerializer oSerializer = new XmlSerializer(obj.GetType());

                // Serialize the object and write to the file
                oSerializer.Serialize(oWriter.BaseStream, obj);
            }
            catch (Exception ex)
            {
                // throw any errors as IO exceptions
                throw new IOException("An error occurred while saving the object", ex);
            }
            finally
            {
                // if a stream is open
                if (oWriter != null)
                {
                    // close it
                    oWriter.Close();
                }
            }
        }

        /// <summary>
        /// Deserializes saved object data of type T in an XML file
        /// located at filePath        
        /// </summary>
        /// <typeparam name="T">Type of object to deserialize</typeparam>
        /// <param name="filePath">The path to open the object from</param>
        /// <returns>An object representing the file or the default value for type T</returns>
        /// <exception cref="System.IO.IOException">Thrown if the file could not be opened. See inner exception for details</exception>
        public static T Open<T>(String filePath)
        {
            // gets access to the file
            StreamReader oReader = null;

            // the deserialized data
            Object data;

            try
            {
                // Open a stream to the file
                oReader = new StreamReader(filePath);

                // Create a deserializer for the object's type
                XmlSerializer oDeserializer = new XmlSerializer(typeof(T));

                // Deserialize the data and store it
                data = oDeserializer.Deserialize(oReader.BaseStream);

                //
                // Return the deserialized object
                // don't cast it if it's null
                // will be null if open failed
                //
                if (data != null)
                {
                    return (T)data;
                }
                else
                {
                    return default(T);
                }
            }
            catch (Exception ex)
            {
                // throw error
                throw new IOException("An error occurred while opening the file", ex);
            }
            finally
            {
                // Close the stream
                oReader.Close();
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top