2012-08-03 141 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