2013-02-08 57 views
3

我知道有关于此主题Stackoverflow已经有几个问题,但我仍然找不到任何关于重复标签的答案。如果我有这样的XML结构:C#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; } 
} 

有没有什么办法可以得到答案,递归地循环该项目而不定义每个可能的公司mbination?

我不想给出一个块列表和一个按钮列表以及一个按钮列表和一个块列表。并为每个新标签添加更多选项。

我也可以在没有反序列化的情况下使用XPath,但是如果我自己不探索它,我不知道关于父/子的信息。对此有帮助吗?

+2

你是什么意思的“得到一个体面的答案”? – RainbowFish 2013-02-08 16:46:12

+0

我们能否看到您想要反序列化的类文件? – 2013-02-08 16:50:30

+1

期望的输出/结果是什么? – Tormod 2013-02-08 16:53:34

回答

0

没有找到我正在寻找的答案,因为我相信你不能做它与反序列化。所以现在我的Block类也有一个Blocks列表,所以我可以递归地循环它们。

0

你需要创建一个递归函数要经过的每个节点,但你可以做的就是:

// 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) 
{ 
    ... 
} 

,这将确定节点是否有子节点是重复的。

1

我相信你问我如何反序列化一个对象数组而不必创建一个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 
{ 
    /// .... 
} 
+0

它也捕捉到以下结构:?因为这就是我想要的。 – ErwinOkken 2013-02-08 18:40:30

+0

是@ErwinOkken,它也会这样工作。 – 2013-02-10 01:16:16

+0

我试过了,但现在我必须给[XmlElement(“Book”)]给Book类。这不是我想要的。 – ErwinOkken 2013-02-11 13:51:48