1

I know you can't add an attribute to an XmlArray which I think is really unhandy. I know I can make a separate class for Phone, however, Phone belongs in Access. I have about 30 more nodes under access. How can I deserialize attribute hasTextField?

    <Access>
       <Phone hasTextField="true">
          <Item description="Skype" />
          <Item description="IP Phone" />
       </Phone>
       <Computer>
          <Item description="PC" />
          <Item description="Laptop" />
       </Computer>
    </Access>


   [XmlRoot("Access")]

    public class Access
    {
       public Access(){}

       [XmlArray("Phone")]
       [XmlArrayItem("Item")]
       public AccessItem[] ItemList;

       [XmlArray("Computer")]
       [XmlArrayItem("Item")]
       public AccessItem[] ItemList;
    }
4
  • Is this read from an xml file? Have you considered using XmlReader? You can choose which properties are assigned that way. Commented Jul 26, 2013 at 14:41
  • You may decorate both Phone and Computer classes with appropriate attribute (=do not use them in the list itself, moreover it doesn't even compile so...) Commented Jul 26, 2013 at 14:41
  • I believe this is a duplicate of this: stackoverflow.com/questions/1012360/… Commented Jul 26, 2013 at 14:43
  • @Kai It's similar, however, the solution in that post is to create a new class, which I'd rather not do, because then I have to create a class for every node. Commented Jul 26, 2013 at 15:01

1 Answer 1

4

You can replace the XmlArray with an XmlElement.

See: How to add an attribute to a collection marked with XmlArrayAttribute?

[XmlType("Access")]
public class Access
{
   [XmlElement("Phone")]
   public AccessItem Phone { get; set; }

   [XmlElement("Computer")]
   public AccessItem Computer { get; set; }
}

public class AccessItem
{
    public AccessItem()
    {
        Items = new List<Item>();
    }

    [XmlAttribute("hasTextField")]
    public bool HasTextField { get; set; }

    [XmlElement("Item")]
    public List<Item> Items { get; set; }
}

[XmlType("Item")]
public class Item
{
    [XmlAttribute("description")]
    public string Description { get; set; }
}

Code:

var data = @"<Access>
   <Phone hasTextField=""true"">
      <Item description=""Skype"" />
      <Item description=""IP Phone"" />
   </Phone>
   <Computer>
      <Item description=""PC"" />
      <Item description=""Laptop"" />
   </Computer>
</Access>";

var serializer = new XmlSerializer(typeof(Access));

Access access;

using(var stream = new StringReader(data))
using(var reader = XmlReader.Create(stream))
{
    access = (Access)serializer.Deserialize(reader);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Nice, just change computer to be computer, and phone to be phone :)
Yeah I didn't notice that. I also changed the fields to properties.
Thanks! Using XmlElement works fabulous, I thought of it but just didn't know how to code it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.