0

是否可以将内部 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 />- XML 反序列化器在文档 (2,2) 中<tile_configuration />引发错误时。

        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 />直接表示和反序列化,它工作正常,调试器进入类ReadXml上的方法,TileConfiguration然后我可以从中管理子<tile />(和后代)元素的解析 - 但这需要重新阅读每次整个 xml 文件。

简而言之; 我是否需要读取和写入整个 XML 文件 - 每次我想使用序列化/反序列化时从根 xml 元素开始,或者有没有办法让我忽略多余的外部元素并直接将相关的子 xml 元素反序列化到他们的没有解析器卡盘错误的代码等效项?

非常感谢。

4

3 回答 3

0

是的。一种想法是加载 xml 并使用 Xpath 查询选择所需的节点。然后反序列化查询结果表示的xml。

于 2012-08-03T17:04:27.563 回答
0

如果您想忽略外部元素并拥有完全控制权和低开销的快速实现,我建议不要使用XMLSerializer而是分别使用XmlReaderand XmlWriter

您还可以通过使用 aXmlReader构建中间 DOM 并使用 anXMLSerializer将 DOM 写入输出文件来进行组合方法。

于 2012-08-03T17:25:09.950 回答
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();
        }
    }
}
于 2012-08-03T20:49:09.027 回答