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,可以包含其他对象的组合,具体取决于下载的文件?有没有更简单的方法来实现这一目标?
.NET在命令行上提供了"xsd.exe"实用程序.
xsd.exe (xmlfilename)在原始xml文件上运行,它将从XML数据文件中派生出XML架构(xsd).
运行xsd.exe (xsd file name) /C它将创建一个C#类,可用于将这样的XML文件反序列化为C#类.
当然,由于它只有一个XML文件可供使用,因此xsd.exe在其派生的XML模式中并不完美 - 但这可能是您开始时的快速起见点.