kittyhawk
kittyhawk

Reputation: 698

Serializing the Same XML Attribute

I am serializing an XML document from a class like so:

<data>
  <name></name>
  <address></address>
  <zip></zip>
  ....a whole bunch more elements
</data>

I would like it to look like this (add an id attribute to every single element):

<data id="">
  <name id=""></name>
  <address id=""></address>
  <zip id=""></zip>
  ....a whole bunch more elements
</data>

How do I set up my class so that the id attribute is added to every single element in my XML? Now, I simply serialize my class properties which might look like so:

public class data 
{
   public string name {get; set;}
   public string address {get; set;}
   public string zip {get; set;}
}

From this example, it looks like I could make each property in my class return a type that contains the id attribute but I'd have to do that for all the properties which seems like overkill.

Upvotes: 0

Views: 231

Answers (2)

Owen Ivory
Owen Ivory

Reputation: 244

I think the best way to do this is create a generic StringData class, and then have your dataclass simply store a list of StringData objects.

public class StringData 
{
   public StringData(string ID, string TEXT)
   {
      id = ID;
      text = TEXT;
   }
   public string id {get; set;}
   public string text {get; set;}
}

public class data 
{
   private Dictionary<string, StringData> dataList;
   public data()
   {
       dataList = new Dictionary<string, StringData>();
   }

   public void setObject(string tag, string id, string text)
   {
      dataList[tag] = new StringData(id, text);
   }

   public StringData getObject(string tag)
   {
       return dataList[tag]; // Use TryParse for error checking here
   }

   public string getID(string tag)
   {
       return dataList[tag].id;  //needs error checking
   }

   public string getText(string tag)
   {
       return dataList[tag].text; //needs error checking
   }
}

At this point, your data definition is now dynamic. You can store hundreds of elements without needing to constantly update your data storage classes.

Of course, the code I wrote was written here, so it might have typos. Also, there is no error checking, so this code is very dangerous, but I think you get the idea I am suggesting.

Upvotes: 0

carlosfigueira
carlosfigueira

Reputation: 87308

Besides rewritting all of your classes to change the string properties to a class containing the string value plus the id value, the easier way would be to post-process the serialized XML and add the ids there.

class Program
{
    const string XML = @"<data>
  <name></name>
  <address></address>
  <zip></zip>
</data>";

    static void Main(string[] args)
    {
        XElement xml = XElement.Parse(XML);
        int id = 0;
        AddIds(xml, ref id);
        Console.WriteLine(xml);
    }

    private static void AddIds(XElement xml, ref int id)
    {
        xml.Add(new XAttribute("id", id.ToString()));
        id++;
        foreach (XElement child in xml.Elements())
        {
            AddIds(child, ref id);
        }
    }
}

If you really want to do it during serialization, you'll need to add a class such as the one below, and replace all the string properties with it.

public class StringWithId {
    [XmlAttribute] public string id;
    [XmlText] public string text;
}

Upvotes: 1

Related Questions