是否可以将内部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 />
中<tile_configuration />
的实例时,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 />
并直接从中反序列化,那么它运行正常,调试器会在ReadXml
类上输入TileConfiguration
方法,然后我可以从中管理解析子<tile />
(和后代)元素 - 但这需要每次都重新读取整个xml文件。
简而言之;我是否需要读取和写入整个XML文件 - 每次我想使用序列化/反序列化时从root xml元素开始,或者是否有办法允许我忽略极端的外部元素并直接将相关的子xml元素反序列化为没有解析器chucking错误的代码等价?
很有责任。
答案 0 :(得分:0)
是。一个想法是加载xml并使用Xpath查询选择所需的节点。然后反序列化由查询结果表示的xml。
答案 1 :(得分:0)
如果你想忽略外部元素并拥有完全控制和低开销的快速实现,我建议不要使用XMLSerializer
,而是分别使用XmlReader
和XmlWriter
。
您还可以通过使用XmlReader
构建中间DOM并使用XMLSerializer
将DOM写入输出文件来实现组合方法。
答案 2 :(得分: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();
}
}
}