【问题标题】:Deserializing XML with namespace and multiple nested elements使用命名空间和多个嵌套元素反序列化 XML
【发布时间】:2014-12-08 19:03:51
【问题描述】:

我正在尝试反序列化以下 xml

<?xml version="1.0" encoding="utf-8"?>
<ns2:myroot xmlns:ns2="http://jeson.com/">
  <item>
    <name>uno</name>
    <price>1.25</price>
  </item>
  <item>
    <name>dos</name>
    <price>2.30</price>
  </item>
</ns2:myroot>

这些类

public class item
{
    [XmlElement(Namespace="")]
    public string name { get; set; }

    [XmlElement(Namespace = "")]
    public double price { get; set; }
}

[XmlRoot("myroot", Namespace="http://jeson.com/")]  //This was http://jeson.com, no slash at the end.
public class myrootNS
{
    [XmlElement(Namespace = "")]
    public item[] item { get; set; }
}

使用这种方法

XmlSerializer serializer = new XmlSerializer(typeof(T), "http://jeson.com/");
XmlReaderSettings settings = new XmlReaderSettings();
using (StringReader textReader = new StringReader(xml))
{
    using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
    {
        return (T)serializer.Deserialize(xmlReader);
    }
}

但不知何故,我不断收到此错误。

System.InvalidOperationException: There is an error in XML document (2, 2). ---> 
System.InvalidOperationException: <myroot xmlns='http://jeson.com/'> was not expected.

正确的做法是什么?该方法适用于没有命名空间的反序列化。

【问题讨论】:

  • 原来我的命名空间最后没有斜线。正如亚历克斯指出的那样,它应该有。

标签: c# xml


【解决方案1】:

问题是 myrootNS 类的命名空间不正确,因为它与 XML 中预期的命名空间不匹配。

[XmlRoot("myroot", Namespace = "http://jeson.com/")]
public class myrootNS
{
    [XmlElement(Namespace = "")]
    public item[] item { get; set; }
}

请注意,Namespace 属性值有一个尾随 /。这是我的反序列化方法:

static T Deserialize<T>(string xml)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    XmlReaderSettings settings = new XmlReaderSettings();
    using (StringReader textReader = new StringReader(xml))
    {
        using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
        {
            return (T)serializer.Deserialize(xmlReader);
        }
    }
}

【讨论】:

  • 您的代码没问题,只需在 myrootNS 类的命名空间末尾添加 / 字符,与您的预期 xml 匹配。
  • 在 XmlSerialezer 构造函数中,您不需要指定命名空间,因为您在 myrootNS 类中指定了名称空间。你可以把 XmlSerializer serializer = new XmlSerializer(typeof(T));
  • 你尝试过你的建议了吗?它打破了一个地雷。
  • 好的,请分享:)
  • 如果在 XML 文件中指定,则在 XmlRootAttribute 中不需要。解决方法是什么?
【解决方案2】:

作为XmlRoot 属性的替代,您还可以使用替代XmlRootAttribute constructor of XmlSerializer 在元素名称或命名空间不同时进行覆盖:

var serializer = new XmlSerializer(typeof(myrootNS), 
                     new XmlRootAttribute                             
                     { 
                         ElementName = "myroot", 
                         Namespace = "http://jeson.com/" 
                     });

【讨论】:

  • 谢谢,原来在 poco 中指定自定义根名称是不够的,我还必须在序列化程序中指定它。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多