【问题标题】:How do I deserialize XML attribute?如何反序列化 XML 属性?
【发布时间】:2020-03-28 12:38:18
【问题描述】:

我是 C# 的新手,所以我希望你们能在这里指导我。我有以下 XML,应该将其转换为带有代码、描述和语言的对象,但我真的很难获得 XML 的“语言”属性值。

目前它只返回'code'和'description'的值,而'lang'返回null。

<?xml version="1.0" encoding="UTF-8"?>
<statisticgroup>
  <code>2049</code>
  <description lang="en-GB">2049</description>
</statisticgroup>
  [Serializable]
  public class XmlStatisticsModel
  {
    [XmlElement ( "code" )]
    public string Code { get; set; }

    [XmlElement ( "description" )]
    public string Description { get; set; }

    [XmlAttribute ( "lang" )]
    public string Lang { get; set; }
  }

【问题讨论】:

  • 代码无法运行。类名和标签名必须相同或使用[XmlRoot("statisticgroup")]
  • 您无法通过这种方式读取语言属性,因为它不是statisticgroup 节点(代表您的类)的属性,而是&lt;Description&gt;node 的属性。将描述更改为一个类并在那里指定属性。
  • 是的,@OguzOzgul 是对的。Description 在这里是一个 ComplexType,而不是一个原始类型
  • 我的回答还包含使用[XmlText] 属性读取描述值 2049。
  • opps.. 我的意思是.. 它是 ComplexType,而不是 SimpleType.. 从某种意义上说,它可能是一个原始类型,它不是从任何东西派生的..

标签: c# xml deserialization


【解决方案1】:

您不能以这种方式读取语言属性,因为它不是&lt;statisticgroup&gt; 节点(代表您的类)的属性,而是&lt;Description&gt;node 的属性。将描述更改为一个类并在其中指定属性,如下所示:

        [Serializable]
        public class Description
        {
            [XmlText]
            public string Value { get; set; }

            [XmlAttribute("lang")]
            public string Lang { get; set; }
        }

        [Serializable]
        [XmlRoot("statisticgroup")]
        public class XmlStatisticsModel
        {
            [XmlElement("code")]
            public string Code { get; set; }

            [XmlElement("description")]
            public Description Description { get; set; }
        }

    static void Main(string[] args)
    {
        string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<statisticgroup>
  <code>2049</code>
  <description lang=""en-GB"">2049</description>
</statisticgroup>
";
        StringReader sr = new StringReader(xml);
        XmlStatisticsModel statisticsModel = (XmlStatisticsModel)new XmlSerializer(typeof(XmlStatisticsModel)).Deserialize(sr);
        Console.WriteLine("Description: {0} (lang: {1})", statisticsModel.Description.Value, statisticsModel.Description.Lang);

    }

【讨论】:

  • 感谢 Oguz,这有助于朝着正确的方向发展 :-)
【解决方案2】:

为您的 XML 架构定义一个 XSD,并让 Microsoft 的 xsd.exe 为您生成类定义。

要获得 XSD 的良好起点,您还可以从 XML 生成 XSD。但是在自动生成的 XSD 上还有一些工作要做。

【讨论】:

    【解决方案3】:

    试试这个代码:

    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
            <statisticgroup>
                <code>2049</code>
                <description lang=""en-GB"">2049</description>
            </statisticgroup>
            ";
            var sr = new StringReader(xml);
            var deserialized = new XmlSerializer(typeof(Statisticgroup)).Deserialize(sr);
        }
    }
    
    [XmlRoot(ElementName = "description")]
    public class Description
    {
        [XmlAttribute(AttributeName = "lang")]
        public string Lang { get; set; }
        [XmlText]
        public string Text { get; set; }
    }
    
    [XmlRoot(ElementName = "statisticgroup")]
    public class Statisticgroup
    {
        [XmlElement(ElementName = "code")]
        public string Code { get; set; }
        [XmlElement(ElementName = "description")]
        public Description Description { get; set; }
    }
    

    结果:

    【讨论】:

      【解决方案4】:

      在这种情况下,您将描述定义为字符串,但在这种情况下,您必须将其定义为自己的元素类型:

      [XmlRoot(ElementName="description")]
      public class Description 
      {
          [XmlAttribute ( "lang" )]
          public string Lang { get; set; }
          [XmlText]
          public string Text { get; set; }
      }
      

      然后在主对象中定义为:

          [XmlElement(ElementName="description")]
          public Description Description { get; set; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-24
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 2020-08-28
        • 1970-01-01
        相关资源
        最近更新 更多