什么时候必须指定根节点来反序列化xml?

时间:2018-05-03 15:26:23

标签: c# xml

我正在尝试反序列化来自Web API服务的xml。它仅在我使用根节点XmlRootAttribute类型实例化XmlSerializer对象时才有效 - 该节点指定根节点和命名空间的名称。如果它是只有一个根节点的正确xml,为什么我需要告诉它根的名称?我看到人们没有这样做的例子。我希望尽可能保持通用。

XML

这是反序列化的代码。我希望注释掉的行能在我没有指定根节点的地方工作,但它会在底部给出错误。

public static T xmlToObject<T>(string strXML)
        {
            XmlRootAttribute xRoot = new XmlRootAttribute();
            xRoot.ElementName = "QIMonthReturn";
            xRoot.Namespace = "QI.Measures.API";

            XmlSerializer serializer = new XmlSerializer(typeof(T), xRoot);
            //XmlSerializer serializer = new XmlSerializer(typeof(T)); 

            StringReader rdr = new StringReader(strXML);

            return (T)serializer.Deserialize(rdr);
        }

错误(我拿出尖括号):

{"There is an error in XML document (2, 2)."}
{"QIMonthReturn xmlns='QI.Measures.API' was not expected."}

类:

public class QIMonth
{
    [XmlElement(ElementName = "Date", DataType = "dateTime")]
    public DateTime Date { get; set; }

    [XmlElement(ElementName = "Numerator", DataType = "boolean")]
    public bool Numerator { get; set; }

    [XmlElement(ElementName = "Denominator", DataType = "boolean")]
    public bool Denominator { get; set; }
}   

[XmlRoot("QIMonthReturn")]
public class QIMonthReturn
{
    public QIMonthReturn()
    {         
        Months = new List<QIMonth>();
    }

    [XmlElement(ElementName = "PatientKey")]
    public string PatientKey { get; set; }

    [XmlArray("Months"), XmlArrayItem("QIMonth")]  
    public List<QIMonth> Months { get; set; }
}

我确实在QIMonth之上有XmlRoot属性但是把它取出来了,不知道是否需要它。

我在添加命名空间的地方:

public static void Register(HttpConfiguration config)
    {           
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Formatters.Clear();
        config.Formatters.Add(new CustomNamespaceXmlFormatter("QI.Measures.API") { UseXmlSerializer = true });
    }

1 个答案:

答案 0 :(得分:0)

如果将命名空间添加到模型类中,则代码将起作用。在你的问题中,你已经编辑了命名空间,所以我做了一个。

<?xml version="1.0" ?>
<QIMonthReturn xmlns="SomeNamespaceHere">
    <PatientKey>25</PatientKey>
    <Months>
        <QIMonth>
            <Date>2018-05-03T11:13:02.1312881-04:00</Date>
            <Numerator>false</Numerator>
            <Denominator>true</Denominator>
        </QIMonth>
    </Months>
</QIMonthReturn>


[XmlRoot("QIMonthReturn", Namespace="SomeNamespaceHere")]
public class QIMonthReturn
{
    public QIMonthReturn()
    {
        Months = new List<QIMonth>();
    }

    [XmlElement(ElementName = "PatientKey")]
    public string PatientKey { get; set; }

    [XmlArray("Months"), XmlArrayItem("QIMonth")]
    public List<QIMonth> Months { get; set; }
}

public static T xmlToObject<T>(string strXML)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));

    StringReader rdr = new StringReader(strXML);

    return (T)serializer.Deserialize(rdr);
}

引用Marc的answer