2009-11-24 64 views
0

我正在寫一個類庫來抽象Web站點上的XML文件中包含的數據。每個XML文件使用相同的根元素:pagepage的後代取決於我下載的特定文件。例如:是否有更簡單的方法來反序列化類似的XML文件?

<!-- 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> 

還有幾個額外的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(); 
    } 
} 

這工作,但我覺得還有就是我沒有看到一個更好的辦法。我在開始這個項目時嘗試使用xsd.exe實用程序。雖然它會盡量減少我編寫的代碼量,但它不像是理想的解決方案。這將是我現在使用的相同方法 - 我會更快地到達那裏。我正在尋找更好的解決方案。所有頁面都有page元素的共同點 - 沒有辦法利用它嗎?根據下載的文件,是否有可能包含可以包含其他對象組合的可串行化的容器類Page?有沒有更簡單的方法來實現這一點?

回答

5

.NET在命令行上提供了一個「xsd.exe」實用程序。

對原始xml文件運行xsd.exe (xmlfilename),它將從XML數據文件中派生XML模式(xsd)。

運行xsd.exe (xsd file name) /C它會創建一個C#類,它可以用來將這樣的XML文件反序列化爲一個C#類。

當然,由於它只有一個XML文件可以繼續使用,因此xsd.exe在它的XML模式中並不完美 - 但這可能是您快速入門的快捷方式的起點。

+0

我在開始這個項目時嘗試使用該實用程序。儘管它會*儘量減少我編寫的代碼量,但它並不是理想的解決方案。這將是我現在使用的相同方法 - 我會更快地到達那裏。我希望有一個更聰明的解決方案。 –

+0

它怎麼樣不覺得「理想」?一個解決方案應該如何「更聰明」?給定一個XML,你有一個定義好的結構 - 你需要多聰明才能解析它?這就是反序列化擅長的。 –

相關問題