2

I need to deserialize some xml to c# objects. This is my class:

[XmlRoot("root")]
[Serializable]
public class MyRoot
{        
    [XmlElement("category")]
    public List<Category> Categories { get; set; }
}

I'm deserializing like this:

root = (MyRoot)new XmlSerializer(typeof(MyRoot)).Deserialize(new StringReader(client.DownloadString(XmlUrl)));

But I want to ignore some Category elements with specified "id" attribute values. Is there some way I can do this?

Simon Karlsson
  • 4,090
  • 22
  • 39
petros
  • 705
  • 1
  • 8
  • 26

3 Answers3

2

Another approach is to have a property named something like ImportCategories with the [XmlElement("category")] attribute and then have Categories as a property that returns a filtered list from ImportCategories using LINQ.

Then your code would do the deserialisaion and then use root.Categories.

Tim Almond
  • 12,088
  • 10
  • 40
  • 50
2

Implementing IXmlSerializable is one way to go, but perhaps an easier path would be simply modifying the XML (using LINQ or XSLT?) ahead of time:

HashSet<string> badIds = new HashSet<string>();
badIds.Add("1");
badIds.Add("excludeme");
XDocument xd = XDocument.Load(new StringReader(client.DownloadString(XmlUrl)));
var badCategories = xd.Root.Descendants("category").Where(x => badIds.Contains((string)x.Attribute("id")));
if (badCategories != null && badCategories.Any())
  badCategories.Remove();
MyRoot root = (MyRoot)new XmlSerializer(typeof(MyRoot)).Deserialize(xd.Root.CreateReader());

You could do something similar on your resulting collection, but it's entirely possible you don't serialize the id, and may not want to/need to otherwise.

Dan Field
  • 20,885
  • 5
  • 55
  • 71
1

To do this the Microsoft way, you would need to implement an IXmlSerializable interface for the class that you want to serialize:

https://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx

It's going to require some hand-coding on your part - you basically have to implement the WriteXml and ReadXml methods, and you get a XmlWriter and a XmlReader interface respectively, to do what you need to do.

Just remember to keep your classes pretty atomic, so that you don't end up custom-serializing for the entire object graph (ugh).

code4life
  • 15,655
  • 7
  • 50
  • 82