带有缩进嵌套标记的C#XML反序列化
本文关键字:C#XML 反序列化 缩进 嵌套 | 更新日期: 2023-09-27 17:58:27
我知道Stackoverflow上已经有几个关于这个主题的问题了,但我仍然找不到任何关于重复标签的答案。如果我有这样一个XML结构:
<root>
<block>
<PositionX>100</PositionX>
<PositionY>100</PositionY>
<block>
<PositionX>10</PositionX>
<PositionY>15</PositionY>
<button>
</button>
</block>
<button>
</button>
</block>
</root>
上述结构可以具有块内按钮和块内块。这是我目前使用的代码,不允许嵌套项目:
反序列化:
public static GUI Deserialize(string filename)
{
GUI gui = null;
XmlSerializer serializer = new XmlSerializer(typeof(GUI));
StreamReader reader = new StreamReader(filename);
gui = (GUI)serializer.Deserialize(reader);
reader.Close();
return gui;
}
根类:
[Serializable()]
[XmlRoot("View")]
public class GUI
{
[XmlArray("Blocks")]
[XmlArrayItem("Block", typeof(GUIBlock))]
public GUIBlock[] Blocks { get; set; }
}
区块:
[Serializable()]
public class GUIBlock
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Position")]
[XmlAttribute("X")]
public int PositionX { get; set; }
[XmlElement("Position")]
[XmlAttribute("Y")]
public int PositionY { get; set; }
[XmlElement("Width")]
public int Width { get; set; }
[XmlElement("Height")]
public int Height { get; set; }
[XmlElement("Background")]
public string Background { get; set; }
[XmlElement("Opacity")]
public int Opacity { get; set; }
// I also want to allow nested Blocks and Buttons in here, but I **dont** explicitly want to say:
[XmlArray("Blocks")]
[XmlArrayItem("Block", typeof(GUIBlock))]
public GUIBlock[] Blocks { get; set; }
}
有没有什么方法可以让我得到一个答案,递归地循环该项,而不定义所有可能的组合?
我不想给块一个块的列表,一个按钮的列表,块的列表和块的列表。并为每个新标签添加更多选项。
我也可以在不进行反序列化的情况下使用XPath,但如果我不亲自研究,我就不知道有关父/子的信息。有什么帮助吗?
我想你在问我如何在不创建包含这些项的ListNode的情况下反序列化对象数组?
例如,您有一个要求,要求您的XML必须如下所示:
<Library>
<Location></Location>
<Book></Book>
<Book></Book>
<Book></Book>
</Library>
它不可能看起来像这样:
<Library>
<Location></Location>
<BookCollection>
<Book></Book>
<Book></Book>
<Book></Book>
<BookCollection>
</Library>
在C#对象中这样做的方式如下:
[Serializable]
public class Library
{
[XmlElement]
public string Location {get;set;}
[XmlElement("Book")]
public Book[] Book {get; set;}
}
public class Book
{
/// ....
}
您需要创建一个递归函数来遍历每个节点,但您可以做的只是:
// This groups all sub-elements of a node by their name.
// If there is more than one node with the same name, .Count() will return > 1
Int32 numberOfSameNameNodes =
node.Elements()
.GroupBy(element => element.Name)
.Count(elementsGroupedByName => elementsGroupedByName.Count() > 1);
// if there are duplicately named sub-nodes then
if (numberOfSameNameNodes > 0)
{
...
}
这将确定一个节点是否有重复的子节点。
没有找到我想要的答案,因为我认为反序列化无法完成。所以现在我的Block类也有一个Block列表,所以我可以递归地循环它们。