2012-08-03 175 views
0

是否有可能將內部xml元素反序列化爲它的平等類?我有下面的XML片段:內部元素的XML反序列化

<?xml version="1.0" encoding="utf-8" ?> 
<tileconfiguration xmlns="http://somenamespace/tile-configuration"> 
    <tile top_left_x="3" top_left_y="1" bottom_right_x="38" bottom_right_y="48"> 
    <child> 
    </child> 
    </tile> 
</tileconfiguration> 

和等價類表示<tile />元素:

[System.Xml.Serialization.XmlRoot(ElementName = "tile")] 
public class Tile : System.Xml.Serialization.IXmlSerializable 
{ 
    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     throw new NotImplementedException(); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

的問題是,每次我試圖反序列化<tile_configuration /><tile />實例 - XML解串器在文檔(2,2)中拋出錯誤。

 System.Xml.Serialization.XmlSerializer serial = new System.Xml.Serialization.XmlSerializer(typeof(Tile)); 
     System.IO.TextReader t = new System.IO.StreamReader("c:\\temp\\deserial.xml"); 
     Tile q = (Tile)serial.Deserialize(t); 

如果我創建一個類來表示<tile_configuration />並直接從deserialise,它工作正常,調試器上進入TileConfigurationReadXml方法從中我就可以管理孩子<tile />的解析(和decendent )元素 - 但這需要每次重新讀取整個xml文件。

簡而言之,我是否需要讀取和寫入整個XML文件 - 每次我想要使用序列化/反序列化或從某種方式允許我忽略extranous外部元素並直接將相關的子xml元素反序列化到它們的根代碼equivilents沒有解析器夾緊錯誤?

非常感謝。

回答

0

如果你想忽略外部元素,並有低開銷的完全控制和快速實施,我建議不要使用XMLSerializer,而是分別使用XmlReaderXmlWriter

您也可以通過使用XmlReader構建中間DOM並使用XMLSerializer將DOM寫入輸出文件來製作組合方法。

0

是的。一個想法是加載xml並使用Xpath查詢選擇所需的節點。然後反序列化由查詢結果表示的xml。

+0

想這可能是這樣的限制範圍。太棒了,非常感謝我會放棄它。 – Yumbelie 2012-08-03 17:21:08

+0

你有沒有遇到過這種情況?我面臨同樣的問題 – Andy 2016-10-10 13:27:49

0

鑑於您已經展示了您的XML,應該沒有必要實現IXmlSerializable。你可以試試這個:

[XmlRoot("tileconfiguration")] 
public class TileConfiguration 
{ 
    [XmlElement("tile")] 
    public List<Tile> Tiles { get; set; } 
} 

[XmlRoot("tile")] 
public class Tile 
{ 
    [XmlAttribute("top_left_x")] 
    public int TopLeftX { get; set; } 

    [XmlAttribute("top_left_y")] 
    public int TopLeftY { get; set; } 

    [XmlAttribute("bottom_right_x")] 
    public int BottomRightX { get; set; } 

    [XmlAttribute("bottom_right_y")] 
    public int BottomRightY { get; set; } 

    [XmlElement("child")] 
    public List<Child> children { get; set; } 
} 

[XmlRoot("child")] 
public class Child 
{ 
} 

XmlSerializer serializer = XmlSerializer(typeof(TileConfiguration)); 
TileConfiguration tileConfiguration = (TileConfiguration)serializer.Deserialize(stream); 

你也可以使用一個XmlReader獲取你想要的元素:

List<Tile> tiles = new List<Tile>(); 
XmlSerializer serializer = XmlSerializer(typeof(Tile)); 

using (XmlTextReader xr = new XmlTextReader(xmlStream)) 
{ 
    while (!xr.EOF) 
    { 
     xr.MoveToContent(); 
     xr.ReadToDescendant("tile"); 

     if (xr.Name == "tile") 
     { 
      string tileXml = xr.ReadOuterXml(); 
      using (StringReader tileReader = new StringReader(tileXml)) 
      { 
       Tile tile = (Tile)serializer.Deserialize(tileReader); 
       tiles.Add(Tile); 
      } 
     } 
     else 
     { 
      xr.ReadEndElement(); 
     } 
    } 
} 
+0

非常感謝!我實現了ISerializable,因爲我給出的例子僅用於說明。在現實世界中,有許多不可序列化的對象嵌套爲子對象,並且需要某些定製的序列化操作,而'自動'XMAttribute []裝飾無法正確處理。 – Yumbelie 2012-08-06 19:52:44