0

I am trying to define C# objects based on this XML:

<UPDs LUPD="86">
  <UPD ID="106">
    <ER R="CREn">
      <NU UID="1928456" />
      <NU UID="1886294" />
      <M>
        <uN>bob ยท </uN>
        <mO>fine :D</mO>
      </M>

So far I have:

public class UDPCollection    
{
    List<UDP> UDPs; 

    public UDPCollection()
    {
        UDPs = new List<UDP>();
    }
}

public class UDP
{
    public int Id;
    public List<ER> ERs;
    public UDP(int id, List<ER> ers)
    {
        Id = id;
        ERs = ers;
    }
}

public class ER
{
    public string LanguageR;

    public ER(string languager)
    {
        LanguageR = languager;
    }
}

My questions: What do elements map to in C#? Classes? What do attributes map to? Properties? Am I going about this the correct way?

DavidRR
  • 18,291
  • 25
  • 109
  • 191
O.O
  • 11,077
  • 18
  • 94
  • 182
  • Why are you doing that? What is the purpose of the code you are trying to write? Your title suggest that something might be very wrong with your approach. XML is a document. Do you need data from XML? Read it. Do you need output XML? Write it. That's it. You don't need to mirror it's structure in objects. โ€“ valentinas Sep 09 '12 at 23:53
  • @valentinas - I receive XML and I read it into an XDocument and now I want to map it to c# classes and properties. โ€“ O.O Sep 09 '12 at 23:58
  • 1
    maybe this will help: http://stackoverflow.com/questions/87621/how-do-i-map-xml-to-c-sharp-objects โ€“ valentinas Sep 10 '12 at 00:02

2 Answers2

1

Use the XmlSerializer class and the XmlRoot, XmlElement and XmlAttribute attributes. For example:

using System.Xml.Serialization;

...

[XmlRoot("UPDs")]
public class UDPCollection
{
    // XmlSerializer cannot serialize List. Changed to array.
    [XmlElement("UPD")]
    public UDP[] UDPs { get; set; }

    [XmlAttribute("LUPD")]
    public int LUPD { get; set; } 

    public UDPCollection()
    {
        // Do nothing
    }
}

[XmlRoot("UPD")]
public class UDP
{
    [XmlAttribute("ID")]
    public int Id { get; set; }

    [XmlElement("ER")]

    public ER[] ERs { get; set; }

    // Need a parameterless or default constructor.
    // for serialization. Other constructors are
    // unaffected.
    public UDP()
    {
    }

    // Rest of class
}

[XmlRoot("ER")]
public class ER
{
    [XmlAttribute("R")]
    public string LanguageR { get; set; }

    // Need a parameterless or default constructor.
    // for serialization. Other constructors are
    // unaffected.
    public ER()
    {
    }

    // Rest of class
}

The code to write out the XML is:

using System.Xml.Serialization;

...

// Output the XML to this stream
Stream stream;

// Create a test object
UDPCollection udpCollection = new UDPCollection();
udpCollection.LUPD = 86;
udpCollection.UDPs = new []
{
    new UDP() { Id= 106, ERs = new [] { new ER() { LanguageR = "CREn" }}}
};

// Serialize the object
XmlSerializer xmlSerializer = new XmlSerializer(typeof(UDPCollection));
xmlSerializer.Serialize(stream, udpCollection);

Not that the XmlSerializer adds additional namepsaces but it can parse XML without them if needed. The output of the above is:

<?xml version="1.0"?>
<UPDs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" LUPD="86">
    <UPD ID="106">
       <ER R="CREn" />
    </UPD>
</UPDs>

Use the Deserialize() method to parse it from XML into an object.

akton
  • 14,148
  • 3
  • 43
  • 47
0

XML elements and attributes don't necessarily map to anything in particular in C#. You can make them map to classes and properties if you want, but it's not required.

That said, if you want to map your existing XML to some sort of C# data structures, the way you're doing it seems reasonable - I'd just recommend replacing your public fields with actual properties, and maybe making the list properties a less specific type - say, IEnumerable, or ICollection, or IList if they really need to be in order.

ekolis
  • 6,270
  • 12
  • 50
  • 101