无法反序列化只有一个节点的XML文件;根节点

时间:2011-12-06 16:15:06

标签: c# xml

这是我正在尝试反序列化的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<d:MyItem xmlns:d="http://someurl" xmlns:m="http://someotherurl">This is a string</d:MyItem>

xsd tool生成了以下类:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://someurl")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://someurl", IsNullable=false)]
public partial class MyItem {

    private object[] itemsField;

    /// <remarks/>
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

我目前正在尝试反序列化xsd用于生成类的相同xml:

var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<d:MyItem xmlns:d=\"http://someurl\" xmlns:m=\"http://someotherurl\">This is a string</d:MyItem>";
var deserialized = Deserialize<MyItem>(xml);

Deserialize<>的位置:

private static T Deserialize<T>(string xml)
{
    var xmlDocument = XDocument.Parse(xml);
    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(xmlDocument.CreateReader());
}

问题是虽然Deserialize返回一个实例(非空),但其中的Items属性为null,即它没有被反序列化。

我如何从此XML中获取字符串?

3 个答案:

答案 0 :(得分:3)

XSD.exe期望您的根文档元素是一个复杂类型,但在您的情况下,它是一个简单的字符串,因此XSD.exe中的各种假设会导致问题。它生成的错误架构只是几个问题中的第一个。

最简单的解决方案是忽略XSD.exe并只创建自己的XML可序列化类:

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://someurl")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://someurl", IsNullable = false)]
public partial class MyItem
{
    [System.Xml.Serialization.XmlTextAttribute]
    public string Value { get; set; }
}

另外,我不确定你为什么在Deserialize中使用XDocument.Parse。你可以像这样简化它:

private static T Deserialize<T>(string xml)
{
    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(new StringReader(xml));
}

以下是完整的工作代码:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://someurl")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://someurl", IsNullable = false)]
    public partial class MyItem
    {
        [System.Xml.Serialization.XmlTextAttribute]
        public string Value { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<d:MyItem xmlns:d=\"http://someurl\" xmlns:m=\"http://someotherurl\">This is a string</d:MyItem>";
            var deserialized = Deserialize<MyItem>(xml);
            // Result:  deserialized.Value == "This is a string"
        }

        private static T Deserialize<T>(string xml) where T : new()
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(new StringReader(xml));
        }
    }
}

答案 1 :(得分:0)

您的xml对我来说不正确,请尝试序列化此类的实例并查看生成的xml。我认为必须有像

这样的东西
<?xml version="1.0" encoding="utf-8"?>
<d:MyItem xmlns:d="http://someurl" xmlns:m="http://someotherurl">
<ArrayOfItems>
<Item>...</Item>
...
</ArrayOfItems>
</d:MyItem>

如果要反序列化xml,则应该有一个类

public partial class MyItem {

/// <remarks/>
public String Item{ get; set;  }
}

并拥有xml

<?xml version="1.0" encoding="utf-8"?>
<d:MyItem xmlns:d="http://someurl" xmlns:m="http://someotherurl">
<Item>some text</Item>    
</d:MyItem>

答案 2 :(得分:0)

如果您使用此xml,那么您的XML就会出现问题,那么您可以使用您的代码对其进行去保护。

var xml = "<MyItem xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://someurl\">  <Items>    <anyType xsi:type=\"xsd:string\">This is string</anyType>  </Items></MyItem>";

这将从xml

中为您提供字符串