反序列化具有多个元素属性的XML文件 - 属性未被反序列化

25

使用C# .Net 4 -- XML示例(实际示例有6个属性)

<TestXML>
  <TestElement attr1="MyAttr" attr2="1" DateAdded="">25</TestElement>
</TestXML>

我的类定义如下:

public class TestXML() {
   public TestXML() {}

   public int TestElement {get; set;}
   [XmlAttribute]
   public string attr1 {get; set;}
   [XmlAttribute]
   public string attr2 {get; set;}
   [XmlIgnore]
   public DateTime DateAdded {get; set;}
   [XmlAttribute("DateAdded")]
   public string dateadded {
      get{ return (DateAdded == null ? "" : DateAdded.ToString();}
      set{ if(!value.Equals("")) DateAdded = DateTime.Parse(value);}
   }
}

现在是反序列化的代码:

string xml = "<TestXML><TestElement attr1=\"MyAttr\" attr2=\"1\" DateAdded=\"\">26</TestElement></TestXML>"
using (StringReader sr = new StringReader(xml)) {
   XmlSerializer serializer = new XmlSerializer(typeof(TestXML));
   TestXML myxml = (TestXML)serializer.Deserialize(sr);
}

现在我们得到的结果是(在VS中查看对象):

myxml
  attr1         |  null
  attr2         |  null
  TestElement   |  25

完全不知道为什么属性无法反序列化。

1
"<TestElement>" 仅指 public int TestElement {get;set;} - Marc Gravell
这个问题的目标是让代码能够正确地格式化XML。 - Richard Wheeler
4个回答

47

为此,您需要两个级别:

[XmlRoot("TestXML")]
public class TestXml {
    [XmlElement("TestElement")]
    public TestElement TestElement { get; set; }
}

public class TestElement {
    [XmlText]
    public int Value {get;set;}

    [XmlAttribute]
    public string attr1 {get;set;}

    [XmlAttribute]
    public string attr2 {get;set;}
}
请注意,> 26 < 可能也会导致问题(空格);您可能需要将其作为字符串而不是整数。

已更正值周围的空格,将其重新格式化为两个类,但第一个类上的引用变量返回 null; - Richard Wheeler
1
@pyTeaParty 只需将 public TestElement {get;set;} 更改为 public TestElement TestElement {get;set;} - e_ne
啊,我忘记了匹配元素名称,所以两个类是我更大的测试的解决方案,非常感谢 @Eve。 - Richard Wheeler
没问题@MarcGravell,我发现这个网站在我遇到的各种问题上非常有帮助。这是我第一次在这里发布问题。现在我有了一个账户,我可以做出更多贡献。 - Richard Wheeler
我发现当元素包含前导和/或尾随空格时,这种模式非常有帮助。反序列化器将使用“set”方法来删除空格,或执行您需要的其他逻辑。 // 后备值 private string _attr1; // 可见值 [XmlAttribute] public string attr1 { get { return _attr1; } set { _attr1 = value.Trim(); } } - pwrgreg007

1

您正在定义 TestElement 上的属性,而应该定义在 TestXML 上。例如:

@"<TestXML attr1=""MyAttr"" attr2=""1"">
      <TestElement>26</TestElement>
  </TestXML>"

XML格式正确,我怀疑问题在类定义中,只是看不出需要做什么,因为其他示例显示相同的设置,只有一个属性。 - Richard Wheeler
@pyTeaParty XML在语法上是正确的,但我们不知道他想让代码适应它还是想了解为什么它不起作用。我认为指出XML应该如何才能使他的代码工作是有用的。 - e_ne
谢谢,我正在尝试让代码与XML配合工作。 - Richard Wheeler

-1

我刚刚运行了一个测试,对你的对象进行序列化/反序列化,看起来一切正常。

测试:

TestXML obj = new TestXML{ attr1 = "Attrib1", attr2 = "Attrib2", DateAdded = DateTime.Now, TestElement = 44};

XmlSerializer serializer = new XmlSerializer(typeof(TestXML));
using (FileStream stream = new FileStream(@"C:\StackOverflow.xml", FileMode.OpenOrCreate))
{
    serializer.Serialize(stream, obj);
}

using (FileStream stream = new FileStream(@"C:\StackOverflow.xml", FileMode.Open))
{
    TestXML myxml = (TestXML)serializer.Deserialize(stream);
}

所有属性已成功反序列化。

结果:

enter image description here

Xml:

<?xml version="1.0"?>
<TestXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attr1="Attrib1" attr2="Attrib2" DateAdded="10/01/2013 9:46:23 a.m.">
  <TestElement>44</TestElement>
</TestXML>

仔细看,我发现你首先对对象进行了序列化。显然,XML不匹配,所以我的类定义是错误的。 - Richard Wheeler

-1
作为已接受答案的补充说明。请确保XML元素不包含像这样的nil="true"属性:
<TestXML>
  <TestElement attr1="MyAttr" attr2="1" DateAdded="" xsi:nil="true">25</TestElement>
</TestXML>

根据我的经验,反序列化器不会反序列化标记为 null(nil)的元素的属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接