【问题标题】:Deserializing XML File with multiple element attributes - attributes are not deserializing反序列化具有多个元素属性的 XML 文件 - 属性未反序列化
【发布时间】:2012-12-24 03:03:42
【问题描述】:

使用 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

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

【问题讨论】:

  • &lt;TestElement&gt; 仅指向public int TestElement {get;set;}
  • 这个问题的目标是让代码工作,xml格式正确。

标签: c# .net xml serialization


【解决方案1】:

为此,您需要两个级别:

[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;}
}

注意&gt; 26 &lt; 也可能导致问题(空格);你可能需要它是一个字符串而不是一个 int。

【讨论】:

  • 更正了值周围的空格,将其重新格式化为两个类,但是第一个类上的引用变量返回 null;
  • @pyTeaParty 只需将:public TestElement {get;set;} 更改为:public TestElement TestElement {get;set;}。
  • 啊,忘了匹配元素名称,所以是的,这两个类是我更大的测试中的解决方案,我非常感谢@Eve
  • 不是问题@MarcGravell 我发现这个网站对我遇到的各种问题非常有帮助。我第一次在这里发布问题。现在我有了一个帐户,我可以贡献更多。
  • 我发现当元素包含前导和/或尾随空格时,这种模式非常有用。反序列化器将使用 'set' 方法删除空格,或执行您需要的其他逻辑。 // 支持值私有字符串 _attr1; // 可见值 [XmlAttribute] public string attr1 { get { return _attr1; } 设置 { _attr1 = value.Trim(); } }
【解决方案2】:

您在TestElement 上定义属性,而它们应该在TestXML 上。示例:

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

【讨论】:

  • XML 的格式是正确的 我怀疑问题出在类定义中,只是看不到需要做什么,因为其他示例显示了相同的设置,但只有一个属性。
  • @pyTeaParty XML 在语法上是正确的,但我们不知道他是否希望代码适应它或理解它为什么不起作用。我认为指出 XML 应该如何让他的代码工作会很有用。
  • 感谢我试图让代码与 XML 一起工作。
【解决方案3】:

我刚刚对您的对象进行了序列化/反序列化测试,它似乎工作正常

测试:

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);
}

所有属性都反序列化了。

结果:

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 不匹配,所以我的类定义是错误的。
【解决方案4】:

作为已接受答案的附加说明。确保 xml 元素不包含这样的 nil="true" 属性:

<TestXML>
  <TestElement attr1="MyAttr" attr2="1" DateAdded="" xsi:nil="true">25</TestElement>
</TestXML>

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多