2008-09-16 6 views
0

Ich arbeite an einer Reihe von Klassen, die zum Serialisieren in XML verwendet werden. Das XML wird nicht von mir kontrolliert und ist recht gut organisiert. Leider gibt es mehrere Sätze von verschachtelten Knoten, deren Zweck es ist, eine Sammlung ihrer Kinder zu speichern. Basierend auf meinen derzeitigen Kenntnissen der XML-Serialisierung benötigen diese Knoten eine andere Klasse..NET XML-Seralisierung

Gibt es eine Möglichkeit, eine Klasse serialisieren zu einer Reihe von XML-Knoten anstelle von nur einer. Weil ich fühle mich wie ich so klar wie Schlamm ich zu sein, sagen wir haben das 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> 

Idealerweise 3 Klassen am besten wäre. Eine Klasse root mit Sammlungen von user und group Objekte. Allerdings Beste, was ich herausfinden kann, ist, dass ich eine Klasse für root, muß users, user, groups und group, wo users und groups nur Sammlungen von user und group enthalten sind, und root enthält ein users und groups Objekt.

Wer da draußen, wer weiß besser als ich? (Lüge nicht, ich weiß, dass es da ist).

Antwort

6

Verwenden Sie nicht die ? Es ist verdammt gut und macht Dinge wie diese wirklich einfach (ich benutze es ziemlich viel!).

Sie können einfach Ihre Klasse Eigenschaften mit einigen Attributen schmücken und der Rest alle für Sie getan wird ..

Haben Sie mit XmlSerializer betrachtet oder gibt es einen besonderen Grund, warum nicht?

Heres ein Code-Snippet der alle erforderlichen Arbeiten der oben serialisiert werden (in beide Richtungen) zu erhalten:

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

Ich benutze den XMLSerializer, aber am besten kann ich sagen, Sie können nur einen einzelnen Elementnamen auf eine Klasse oder Eigenschaft anwenden. Ich habe mehrere Zwischenklassen, die nur Sammlungen anderer Objekte enthalten. Das Ergebnis ist das richtige XML, aber ein Schmerz in den Hintern, um mich zu instantiieren. –

+0

Code zur Demo hinzugefügt :) –

+0

@Rob Cooper: +1 für mich gegen den Code Punch zu schlagen. – user7116

0

Sie müssten nur Benutzer als ein Array von Benutzerobjekte definiert haben. Der XmlSerializer wird es für Sie entsprechend rendern.

Siehe diesen Link für ein Beispiel: http://www.informit.com/articles/article.aspx?p=23105&seqNum=4

Zusätzlich würde ich Visual Studio empfiehlt eine XSD und mit dem Kommandozeilen-Utility xsd.exe zu generieren für Sie die Klassenhierarchie auszuspucken, wie pro http://quickstart.developerfusion.co.uk/quickstart/howto/doc/xmlserialization/XSDToCls.aspx

0

Ich schrieb diese Klasse zurück in den Tag, um zu tun, was ich denke, ist ähnlich, was Sie versuchen zu tun. Sie würden Methoden dieser Klasse für Objekte verwenden, die Sie in XML serialisieren möchten. Zum Beispiel, wenn ein Mitarbeiter ...

mit Utilities; mit System.Xml.Serialisierung;

[XmlRoot ("Mitarbeiter")] public class Employee { 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); 
} 

}

Dieser Code ausgeben soll:

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

Der Objekttyp (Employee) serializable sein muss. Versuchen Sie [Serializable (true)]. Ich habe eine bessere Version dieses Codes irgendwo, ich lernte gerade, als ich es schrieb. Wie auch immer, schauen Sie sich den Code unten an. Ich benutze es in einem Projekt, also funktioniert es definitiv.

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(); 
      } 
     } 
    } 
}