2016-03-08 3 views
1

Мне нужно десериализовать некоторые объекты xml для C#. Это мой класс:C# - десериализация XML - игнорирование элементов с атрибутом

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

Я десериализация, как это:

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

Но я хочу, чтобы игнорировать некоторые элементы Категории с заданными значениями атрибутов «ID». Есть ли способ сделать это?

+1

Просто постэтериализованный объект (пройдите список, проверьте идентификатор и удалите). Если вы не можете этого сделать, пожалуйста, объясните, почему. – Sinatr

+0

Это односторонняя улица или вам нужно десериализовать XML позже? – user1859022

ответ

2

Реализация IXmlSerializable это один путь, но возможно, более легкий путь, будет просто изменяя XML раньше времени (с помощью LINQ или XSLT?):

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

Вы могли бы сделать что-то подобное на вашем результате сбора , но вполне возможно, что вы не сериализуете id и, возможно, не захотите/необходимости в противном случае.

+0

Спасибо! Мне просто интересно, если есть какой-то атрибут C#, чтобы сделать это – petros

+0

Нет. Не без пользовательских 'IXmlSerializable' –

1

Чтобы сделать это, как Microsoft, вам потребуется реализовать IXmlSerializable интерфейс для класса, который вы хотите сериализовать:

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

Это будет требовать некоторые ручного кодирования с вашей стороны - вы в основном необходимо реализовать методы WriteXml и ReadXml, и вы получите соответственно XmlWriter и XmlReader, чтобы выполнить то, что вам нужно.

Просто помните, чтобы ваши классы были довольно атомарными, чтобы вы не закончили сериализацию для всего графа объектов (ugh).

2

Другой подход заключается в том, чтобы иметь свойство, названное как ImportCategories, с атрибутом [XmlElement ("category")], а затем иметь Категории как свойство, которое возвращает отфильтрованный список из ImportCategories с помощью LINQ.

Тогда ваш код сделает deserialisaion, а затем используйте root.Categories.

Смежные вопросы