使用属性可以使用XmlReader对数据进行分段

时间:2013-10-24 12:29:38

标签: xml

我正在使用XML文件和XmlReader来填充类对象。

这是我的类对象:

public class WikiMeta
{
    string _subject;

    public List<WikiArticle> Articles = new List<WikiArticle>();

    public List<WikiGroup> Groups = new List<WikiGroup>();

    public string PageMetaDescription { get; set; }

    public string PageTitle { get; set; }

    public string Route { get; set; }

    public string Subject { get; set; }
}

以下是XML示例:

<AllMeta>
  <WikiMeta>
    <Subject>The Subject</Subject>
    <PageTitle>Page title</PageTitle>
    <PageMetaDescription>Page meta description</PageMetaDescription>
    <Articles>
      <WikiArticle>
        <FileName>file.txt</FileName>
      </WikiArticle>
    </Articles>
    <Groups>
      <WikiGroup>
        <Name>Main group</Name>
      </WikiGroup>
      <WikiGroup>
        <Name>Secondary group</Name>
      </WikiGroup>
    </Groups>
  </WikiMeta>
</AllMeta>

使用XmlReader类,XML会自动映射到我的类属性,但是,我现在要介绍文章类型的变体。对我来说,有两个明显的解决方案是:

  1. 将WikiGroup替换为2个新组PeerGroup和ChildGroup
  2. 在WikiGroup中添加一个Type元素
  3. 但是,我想知道是否有一种方法可以将属性添加到WikiGroup并将其映射到我的类中的两个不同的属性,如下所示:

    WikiGroup attr="peer">
            <Name>Main group</Name>
          </WikiGroup>
    
    [XmlAttribute("peer")]
    public WikiGroup PeerGroup { get; set; }
    
    [XmlAttribute("child")]
    public WikiGroup ChildGroup { get; set; }
    

    我不知道这是否可能,但我们非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

我们假设你想要:

<Groups>
  <WikiGroup type="peer">
    <Name>Main group</Name>
  </WikiGroup>
  <WikiGroup type="child">
    <Name>Secondary group</Name>
  </WikiGroup>
</Groups>

您应该将Type属性添加到WikiGroup课程中,如您所说:

public partial class WikiGroup
{
    public string Name { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute("type")]
    public string Type { get; set; }
}

WikiMeta课程中,您可以添加2个属性:

[XmlIgnore]
public WikiGroup PeerGroup
{
    get
    {
        return groupsField.FirstOrDefault(g => g.Type== "peer");
    }
    set
    {
        if (groupsField == null)
            groupsField = new List<WikiGroup>();
        var peerGroup = groupsField.FirstOrDefault(g => g.Type == "peer");
        if (peerGroup != null)
            groupsField.Remove(peerGroup);
        value.Type = "peer";
        groupsField.Add(value);
    }
}

[XmlIgnore]
public WikiGroup ChildGroup
{
    get
    {
        return groupsField.FirstOrDefault(g => g.Type == "child");
    }
    set
    {
        if (groupsField == null)
            groupsField = new List<WikiGroup>();
        var childGroup = groupsField.FirstOrDefault(g => g.Type == "child");
        if (childGroup != null)
            groupsField.Remove(childGroup);
        value.Type = "child";
        groupsField.Add(value);
    }
}

除了新添加的属性,您还必须处理Groups setter:

private List<WikiGroup> groupsField;

public List<WikiGroup> Groups
{
    get
    {
        return this.groupsField;
    }
    set
    {
        if (value.FirstOrDefault(g => g.Type == "peer") == null && PeerGroup != null)
            value.Add(PeerGroup);
        if (value.FirstOrDefault(g => g.Type == "child") == null && ChildGroup != null)
            value.Add(ChildGroup);
        this.groupsField = value;
    }
}

必须这样做才能防止覆盖值类似于下面的对象创建:

WikiMeta o = new WikiMeta()
{
    PeerGroup = new WikiGroup() { Name = "Test Peer" },
    ChildGroup = new WikiGroup() { Name = "Test Child" },
    Groups = new List<WikiGroup>()
};