是否有更简单的方法来反序列化类似的XML文件?

Jus*_*tch 0 c# xml xml-serialization

我正在编写一个类库,它抽象出网站上XML文件中包含的数据.每个XML文件使用相同的根元素:page.page依赖于我正在下载的特定文件的后代.例如:

<!-- http://.../groups.xml -->
<page url="/groups.xml">
  <groups>
    <group id="1" >
      <members>
        <member name="Adrian" />
        <member name="Sophie" />
        <member name="Roger" />
      </members>
    </group>
  </groups>
</page>

<!-- http://.../project.xml?n=World%20Domination -->
<page url="/project.xml">
  <projectInfo>
    <summary classified="true" deadline="soon" />
    <team>
      <member name="Pat" />
      <member name="George" />
    </team>
  </projectInfo>
</page>
Run Code Online (Sandbox Code Playgroud)

最后还有一些我想要下载和处理的XML文件.出于这个原因,我一直试图想出一个很好的,干净的方法来反序列化数据.我尝试了一些方法,但是当我回顾我的代码时,每种方法都让我觉得有点脏.我最新的化身使用以下方法:

internal class Provider
{
    /// <summary>Download information from the host.</summary>
    /// <typeparam name="T">The type of data being downloaded.</typeparam>
    internal T Download<T>(string url) where T : IXmlSerializable, new()
    {
        try
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            var response = (HttpWebResponse)request.GetResponse();
            using (var reader = XmlReader.Create(response.GetResponseStream()))
            {
                // Skip the XML prolog (declaration and stylesheet reference).
                reader.MoveToContent();

                // Skip the `page` element.
                if (reader.LocalName == "page") reader.ReadStartElement();

                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(reader);
            }
        }
        catch (WebException ex) { /* The tubes are clogged. */ }
    }
}

[XmlRoot(TypeName = "groups")]
public class GroupList : List<Group>, IXmlSerializable
{
    private List<Group> _list;

    public void ReadXml(XmlReader reader)
    {
        if (_list == null) _list = new List<Group>();

        reader.ReadToDescendant("group");

        do
        {
            var id = (int)reader["id"];
            var group = new Group(id);

            if (reader.ReadToDescendant("member"))
            {
                do
                {
                    var member = new Member(reader["name"], group);
                    group.Add(member);
                } while (reader.ReadToNextSibling("member"));
            }

            _list.Add(group);
        } while (reader.ReadToNextSibling("group"));

        reader.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效,但我觉得有一种更好的方式,我没有看到.我xsd.exe在启动这个项目时尝试使用该实用程序.虽然它可以最大限度地减少我编写的代码量,但它并不是理想的解决方案.这将是我现在使用的相同方法 - 我会更快地到达那里.我正在寻找更好的解决方案.所有页面都有page共同的元素 - 是不是有办法利用它?是否有可能有一个可序列化的容器类Page,可以包含其他对象的组合,具体取决于下载的文件?有没有更简单的方法来实现这一目标?

mar*_*c_s 5

.NET在命令行上提供了"xsd.exe"实用程序.

xsd.exe (xmlfilename)在原始xml文件上运行,它将从XML数据文件中派生出XML架构(xsd).

运行xsd.exe (xsd file name) /C它将创建一个C#类,可用于将这样的XML文件反序列化为C#类.

当然,由于它只有一个XML文件可供使用,因此xsd.exe在其派生的XML模式中并不完美 - 但这可能是您开始时的快速起见点.