c# - Windows Phone C# 中的 XML 反序列化

标签 c# windows-phone-7 xml-serialization

我正在开发新闻门户的 WP 应用程序,我需要解析各种提要。标准提要如下所示:

<feed>
    <items>
        <item>
            ...
        </item>
        <item>
            ...
        </item>
    </items>
</feed>

我使用此代码对其进行反序列化:

XDocument document = XDocument.Load(xmlStream);
XmlSerializer serializer = new XmlSerializer(typeof(News));
News MainPage = (News)serializer.Deserialize(document.CreateReader());
Dispatcher.BeginInvoke(() => MainPageListBox.ItemsSource = MainPage.DataSet;);

新闻类如下所示:

[XmlRoot("feed")]
public class News
{
    [XmlArray("items")]
    [XmlArrayItem("item")]
    public ObservableCollection<NewsItem> DataSet{ get; set; }
}

这在每个具有此结构的 feed 中都可以正常工作,其中一个 <items>部分。但我也有多个部分的提要,例如:

<feed>
    <items section="part 1">
        <item>
            ...
        </item>
        <item>
            ...
        </item>
    </items>
    <items section="part 2">
        <item>
            ...
        </item>
        <item>
            ...
        </item>
    </items>
</feed>

如果我使用上面的 C# 代码,则只有第一个 <items>部分被解析,其他部分被忽略。我需要为每个 <items> 创建单独的 List 或 ObservableCollection单个 XML feed 中的部分。

有人可以帮我解决这个问题吗?非常感谢。

最佳答案

类(class):

[XmlRoot("feed")]
    public class News
    {
        [XmlArray("items")]
        public List<NewsItemCollection> DataSet { get; set; }

        public News()
        {
            DataSet = new List<NewsItemCollection>();
        }
    }

    public class NewsItemCollection
    {
        [XmlAttribute("section")]
        public string Section { get; set; }

        [XmlElement("item")]
        public ObservableCollection<NewsItem> Items { get; set; }

        public NewsItemCollection()
        {
            Items = new ObservableCollection<NewsItem>();
        }
    }

    public class NewsItem
    {
        public string Title { get; set; }
    }

我的一些用于序列化/反序列化 xml 的帮助器类:

public static class ObjectExtensions
    {
        /// <summary>
        /// <para>Serializes the specified System.Object and writes the XML document</para>
        /// <para>to the specified file.</para>
        /// </summary>
        /// <typeparam name="T">This item's type</typeparam>
        /// <param name="item">This item</param>
        /// <param name="fileName">The file to which you want to write.</param>
        /// <returns>true if successful, otherwise false.</returns>
        public static bool XmlSerialize<T>(this T item, string fileName)
        {
            return item.XmlSerialize(fileName, true);
        }

        /// <summary>
        /// <para>Serializes the specified System.Object and writes the XML document</para>
        /// <para>to the specified file.</para>
        /// </summary>
        /// <typeparam name="T">This item's type</typeparam>
        /// <param name="item">This item</param>
        /// <param name="fileName">The file to which you want to write.</param>
        /// <param name="removeNamespaces">
        ///     <para>Specify whether to remove xml namespaces.</para>para>
        ///     <para>If your object has any XmlInclude attributes, then set this to false</para>
        /// </param>
        /// <returns>true if successful, otherwise false.</returns>
        public static bool XmlSerialize<T>(this T item, string fileName, bool removeNamespaces)
        {
            object locker = new object();

            XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
            xmlns.Add(string.Empty, string.Empty);

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.OmitXmlDeclaration = true;

            lock (locker)
            {
                using (XmlWriter writer = XmlWriter.Create(fileName, settings))
                {
                    if (removeNamespaces)
                    {
                        xmlSerializer.Serialize(writer, item, xmlns);
                    }
                    else { xmlSerializer.Serialize(writer, item); }

                    writer.Close();
                }
            }

            return true;
        }

        /// <summary>
        /// Serializes the specified System.Object and returns the serialized XML
        /// </summary>
        /// <typeparam name="T">This item's type</typeparam>
        /// <param name="item">This item</param>
        /// <returns>Serialized XML for specified System.Object</returns>
        public static string XmlSerialize<T>(this T item)
        {
            return item.XmlSerialize(true);
        }

        /// <summary>
        /// Serializes the specified System.Object and returns the serialized XML
        /// </summary>
        /// <typeparam name="T">This item's type</typeparam>
        /// <param name="item">This item</param>
        /// <param name="removeNamespaces">
        ///     <para>Specify whether to remove xml namespaces.</para>para>
        ///     <para>If your object has any XmlInclude attributes, then set this to false</para>
        /// </param>
        /// <returns>Serialized XML for specified System.Object</returns>
        public static string XmlSerialize<T>(this T item, bool removeNamespaces)
        {
            object locker = new object();

            XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
            xmlns.Add(string.Empty, string.Empty);

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.OmitXmlDeclaration = true;

            lock (locker)
            {
                StringBuilder stringBuilder = new StringBuilder();
                using (StringWriter stringWriter = new StringWriter(stringBuilder))
                {
                    using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
                    {
                        if (removeNamespaces)
                        {
                            xmlSerializer.Serialize(xmlWriter, item, xmlns);
                        }
                        else { xmlSerializer.Serialize(xmlWriter, item); }

                        return stringBuilder.ToString();
                    }
                }
            }
        }
    }

public static class StringExtensions
    {
        /// <summary>
        /// Deserializes the XML data contained by the specified System.String
        /// </summary>
        /// <typeparam name="T">The type of System.Object to be deserialized</typeparam>
        /// <param name="s">The System.String containing XML data</param>
        /// <returns>The System.Object being deserialized.</returns>
        public static T XmlDeserialize<T>(this string s)
        {
            var locker = new object();
            var stringReader = new StringReader(s);
            var reader = new XmlTextReader(stringReader);
            try
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                lock (locker)
                {
                    var item = (T)xmlSerializer.Deserialize(reader);
                    reader.Close();
                    return item;
                }
            }
            catch
            {
                return default(T);
            }
            finally
            {
                reader.Close();
            }
        }
    }

测试运行:

News news = new News();
            news.DataSet.Add(new NewsItemCollection
            {
                Section = "Section1",
                Items = new ObservableCollection<NewsItem>
                    {
                        new NewsItem { Title = "Test1.1" },
                        new NewsItem { Title = "Test1.2" }
                    }
            });
            news.DataSet.Add(new NewsItemCollection
            {
                Section = "Section2",
                Items = new ObservableCollection<NewsItem>
                    {
                        new NewsItem { Title = "Test2.1" },
                        new NewsItem { Title = "Test2.2" }
                    }
            });

            var serialized = news.XmlSerialize();
            var deserialized = serialized.XmlDeserialize<News>();

玩得开心!

关于c# - Windows Phone C# 中的 XML 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11534510/

相关文章:

c# - 读取文本文件跳过一堆行然后继续其他行

windows-phone-7 - 如何在 Windows 手机应用程序中实现错误日志记录?

c# - 如何在运行时更改按钮的背景图像?

c# - xml 序列化基类列表

.net - SGEN 错误反射(reflect)类型

c# - While 循环线程

c# - 将聚合 COUNT 中的 DISTINCT 转换为 LINQ

windows-phone-7 - SkyDrive 的编程访问

c# - 将对象序列化并存储在另一个实现 IXmlSerializable 的对象中

c# - EntityFramework,在配置中找不到指定的store provider,或者是无效的