[英]XmlSerializer filter by namespace
我正在尝试反序列化RSS 2.0 feed,并且我想考虑一些iTunes扩展,但不必直接将它们烘焙到主类中。
使用C#中的XML反序列化器,可能会出现以下情况?
public class RssChannel
{
[XmlElement("title")]
public string Title { get; set; }
[XmlElement("link")]
public string Link { get; set; }
....
[XmlElement(Namespace = "itunes")]
public iTunesExtensions iTunes { get; set; }
}
public class iTunesExtensions
{
[XmlElement("category")]
public string[] Categories { get; set; }
}
我希望可以解析如下内容:
<channel>
<itunes:category text="Society & Culture"/>
<itunes:category text="Society & Culture"/>
<itunes:category text="Society & Culture"/>
</channel>
可以在模块化程度更高的地方做类似的事情吗? 还是我坚持将其烘焙到主要班级?
bizzehdee,
为了将第一级设置为“”,您需要将其设置为类的根目录和名称:
[XmlRoot("channel")]
public class channel
对于以下示例,我将其保留为RssChannel。
我假设您打算使用比iTunes更多的平台,所以iTunes仍然有自己的类。 使用较少的代码即可完成此操作的方法是使用列表而不是数组:
public List<iTunes> iTunes;
类别将具有自己的类,因此您可以在任何平台上使用类别。 注意XmlAttribute的使用。 这将在同一行中包含类别名称:
public class iTunes
{
public List<Category> Categories { get; set; }
}
public class Category
{
[XmlAttribute("category")]
public string category { get; set; }
}
您可以使用静态类来帮助您序列化和反序列化数据。 静态类中的以下两种方法会有所帮助:
// Save XML data.
public static void SaveData(ref RssChannel instance) {}
// Retrieve XML data.
public static RssChannel DeserializeData() {}
使用这些方法的最佳方法是首先使用DeserializeData()方法获取RssChannel的实例,例如:
RssChannel foo = StaticClassName.DeserializeData();
对其进行更改,然后通过将其作为对SaveData()方法的引用进行传递来保存该实例,例如:
SaveData(ref foo);
这是一个完整的工作示例:
public static class XML
{
// Serializes the passed instance of RssChannel into XML file, and saves to runtime memory.
public static void SaveData(ref RssChannel instance)
{
// Objects:
StreamWriter sw = new StreamWriter("yourXmlFile.xml");
XmlSerializer serializer = new XmlSerializer(typeof(RssChannel));
// Save data.
serializer.Serialize(sw, instance);
sw.Close();
}
// Deserializes data from the XML file, and returns the instance.
public static RssChannel DeserializeData()
{
// Objects:
RssChannel channelData = new RssChannel();
XmlSerializer serializer = new XmlSerializer(typeof(RssChannel));
List<iTunes> iTunesList = new List<iTunes>();
if (File.Exists("yourXmlFile.xml"))
{
FileStream stream = new FileStream("yourXmlFile.xml", FileMode.Open);
// Deserialize data.
channelData = (RssChannel)serializer.Deserialize(stream);
stream.Close();
// Add data from deserialized iTunes list to list instance.
if (channelData.iTunesList != null)
iTunesList = channelData.iTunesList;
}
// Add data to RootData object lists.
channelData.iTunesList = iTunesList;
return channelData;
}
}
[XmlRoot("RssChannel")]
public class RssChannel
{
[XmlAttribute("Title")]
public string Title; // { get; set; }
[XmlAttribute("Link")]
public string Link; // { get; set; }
public List<iTunes> iTunesList; // { get; set; }
}
public class iTunes
{
public List<Category> Categories; // { get; set; }
}
public class Category
{
[XmlAttribute("category")]
public string category; // { get; set; }
}
您可以使用这样的类和静态方法:
private void AnyMethod()
{
// To get an instance of your RssChannel class with all the data:
RssChannel rssChannel = XML.DeserializeData();
// Do anything with the data. Example below:
iTunes newITunes = new iTunes();
List<Category> categoryList = new List<Category>();
Category newCategory1 = new Category(); // Create new categories.
newCategory1.category = "Allegro";
categoryList.Add(newCategory1);
Category newCategory2 = new Category();
newCategory2.category = "Prestissimo";
categoryList.Add(newCategory2);
newITunes.Categories = categoryList; // Add the categories to list.
rssChannel.iTunesList.Add(newITunes); // Add that list to iTunes list.
// Now, to save the data, pass a reference to the instance we just worked on:
XML.SaveData(ref rssChannel);
}
这将产生一个如下文件:
<?xml version="1.0" encoding="utf-8"?>
<RssChannel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<iTunesList>
<iTunes>
<Categories>
<Category category="Allegro" />
<Category category="Prestissimo" />
</Categories>
</iTunes>
</iTunesList>
</RssChannel>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.