【问题标题】:Serialize XML same tag twice序列化 XML 相同的标签两次
【发布时间】:2012-07-02 16:24:44
【问题描述】:

我有问题:

我必须将类序列化为 XML 文件。但是两个属性必须同名:

所需的xml:

<?xml version="1.0"?>
<Test>
  <HeaderText>
    <Tag1>AAA</Tag1>
  </HeaderText>
  <HeaderText>
    <Tag2>BBB</Tag2>
  </HeaderText>
</Test>

我不需要将它反序列化回对象。

代码:

public class Header1
{
    [XmlElement("Tag1")]
    public String Tag1 { get; set; }
}

public class Header2
{
    [XmlElement("Tag2")]
    public String Tag2 { get; set; }
}

public class Test
{
    [XmlElement("HeaderText")]
    public Header1 Header1 { get; set; }

    [XmlElement("HeaderText")]
    public Header2 Header2 { get; set; }
}

var doc = new Test
{
    Header1 = new Header1 { Tag1 = "AAA" },
    Header2 = new Header2 { Tag2 = "BBB" }
};

var xml = new XmlSerializer(typeof(Test));
using (var fs = new FileStream("test.xml", FileMode.Create))
{
    xml.Serialize(fs, doc);
}

此代码不起作用。

命名空间“”中的 XML 元素“HeaderText”已存在于当前范围内。使用 XML 属性为元素指定另一个 XML 名称或命名空间。

我能做什么?

现实世界的例子:

  <Product>
    <RecordReference>1-15991</RecordReference>
    <MainSubject>
      <MainSubjectSchemeIdentifier>66</MainSubjectSchemeIdentifier>
      <SubjectCode>2</SubjectCode>
    </MainSubject>
    <MainSubject>
      <MainSubjectSchemeIdentifier>20</MainSubjectSchemeIdentifier>
      <SubjectHeadingText>Venäläisiä kirjoja: uskonto, teosofia, mystiikka</SubjectHeadingText>
    </MainSubject>
</Product>

【问题讨论】:

    标签: c# .net xml exception-handling xml-serialization


    【解决方案1】:

    使用数组:

    public class Test
    {
        [XmlElement("HeaderText")]
        public string[] HeaderText { get; set; }
    }
    

    然后:

    var doc = new Test
    {
        HeaderText = new[] { "AAA", "BBB" }
    };
    var xml = new XmlSerializer(typeof(Test));
    using (var fs = new FileStream("test.xml", FileMode.Create))
    {
        xml.Serialize(fs, doc);
    }
    

    也适用于List&lt;string&gt;。


    更新:

    使用复杂对象定义模型:

    public class Header
    {
        public string Tag { get; set; }
    }
    

    然后你就有了这个模型的集合:

    public class Test
    {
        [XmlElement("HeaderText")]
        public Header[] HeaderText { get; set; }
    }
    

    然后你序列化:

    var doc = new Test
    {
        HeaderText = new[] 
        { 
            new Header { Tag = "AAA" }, 
            new Header { Tag = "BBB" }
        }
    };
    var xml = new XmlSerializer(typeof(Test));
    using (var fs = new FileStream("test.xml", FileMode.Create))
    {
        xml.Serialize(fs, doc);
    }
    

    【讨论】:

    • 也适用于public List&lt;string&gt; HeaderText {},更容易添加/删除项目。
    • @Tisho,是的,我已更新我的答案以包含此信息。
    • 谢谢,它适用于简单的属性。请查看有问题的更新代码。
    • :(我有不同的类具有不同的属性(Header1,Header2)。
    • 这似乎是一个错误的方法。在您展示的 XML 中,您似乎想要表示一个集合。所以这就是我建议你在你的模型中使用的。如果你不这样做,你可能需要编写大量的管道代码。
    【解决方案2】:

    您可以告诉序列化程序忽略您当前的属性,并添加一个新属性以进行序列化:

    public class Test
    {
        [XmlIgnore]
        public String Header1 { get; set; }
    
        [XmlIgnore]
        public String Header2 { get; set; }
    
        [XmlElement("HeaderText")]
        public String[] HeaderText
        {
            get{  return new[]{Header1,Header2};   }
            set{  if(value.Length == 2) { Header1 = value[0]; Header2 = value[1];} }
        }
    }
    

    现场示例:http://rextester.com/YVEF64085

    【讨论】:

      猜你喜欢
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多