将xml的一部分反序列化为字符串

时间:2014-10-23 09:46:09

标签: c# xml deserialization

是否可以反序列化以下XML:

<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>

进入这个对象:

public class MyObject {
    public string Test { get; set; }
    public string Something { get; set; }
}

将此作为预期输出(此时XmlException: Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 1, position 50.}

失败
[TestMethod]
public void TestDeserialization()
{
    var s = "<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>";

    var o = s.DeSerialize<MyObject>();
    Assert.AreEqual("Hi hello", o.Test);
    Assert.AreEqual("<Else><With><SubItems count='5'>hello world</SubItems></With></Else>", o.Something);
}

public static class Xml
{
    public static T DeSerialize<T>(this string xml) where T : new()
    {
        if (String.IsNullOrEmpty(xml))
        {
            return new T();
        }
        var xmlSer = new XmlSerializer(typeof(T));
        using (var stream = new StringReader(xml))
            return (T)xmlSer.Deserialize(stream);
    }
}

1 个答案:

答案 0 :(得分:3)

一个选项可能是实现IXmlSerializable,因此您手动将内部Xml读入Something属性:

public class MyObject: IXmlSerializable 
{
    public string Test { get; set; }
    public string Something { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema() { return null; }

    public void ReadXml(System.Xml.XmlReader reader)
    {       
        if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyObject")
        {           
            Test = reader["Test"];
            if (reader.ReadToDescendant("Something"))
            {
                Something = reader.ReadInnerXml();
            }
        }                   
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        throw new NotImplementedException();
    }   
}

public static class Program
{
    public static void Main()
    {   
        var myObjectXmlString = "<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>";    
        var myObject =(MyObject) new XmlSerializer(typeof(MyObject)).Deserialize(new StringReader(myObjectXmlString));
        Console.WriteLine(myObject.Something);
    }
}

另一个选项可能是将Something转换为XmlElement类型的属性,因此Xml的内部随机片段将被序列化为Xml而不是字符串(您仍然可以通过获取它来将其作为字符串检索OuterXml):

public class MyOtherObject 
{
    public string Test { get; set; }    
    public XmlElement Something { get; set; }
    public string SomethingString
    {
        get { return Something.OuterXml; }
    }
}

public static class Program
{
    public static void Main()
    {   
        var otherObjectXmlString = "<MyOtherObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyOtherObject>";   
        var otherObject =(MyOtherObject) new XmlSerializer(typeof(MyOtherObject)).Deserialize(new StringReader(otherObjectXmlString));
        Console.WriteLine(otherObject.SomethingString);             
    }
}

我创建了this fiddle,因此您可以尝试一下。