当xml包含使用XmlSerializer的元素列表时,反序列化xml

时间:2014-01-08 22:16:55

标签: c# xml xml-serialization

我已经获得了一些XML,我希望将其反序列化为类对象,但是我遇到的问题似乎是列表,即subscription_product和product_id。基本上我的员工和产品列表中只有0条记录

以下是xml

的示例
<?xml version="1.0" "encoding=utf-8"?>
  <subscription_product consultant_end_user_id="4" farm_id="6" 
     farm_name="Farm Name"   
     farmer_end_user_id="5" 
     subscription_expiry="2014-01-01" 
     subscription_id="7">
    <associate_end_user_id>1</associate_end_user_id>
    <associate_end_user_id>2</associate_end_user_id>
    <associate_end_user_id>3</associate_end_user_id>
    <product_id>8</product_id>
    <product_id>9</product_id>
    <product_id>10</product_id>
  </subscription_product>

这是映射到此

的类对象
[XmlRoot("subscription_product")]
public class Subscription
{
    public Subscription()
    {
        Associates = new List<int>();
        Products = new List<int>();
    }

    [XmlAttribute(AttributeName="subscription_expiry")]
    public DateTime Expiry { get; set; }

    [XmlAttribute(AttributeName = "subscription_id")]
    public int Id { get; set; }

    [XmlAttribute(AttributeName = "farmer_end_user_id")]
    public int FarmOwnerId { get; set; }

    [XmlAttribute(AttributeName = "farm_name")]
    public string FarmName { get; set; }

    [XmlAttribute(AttributeName = "consultant_end_user_id")]
    public int ConsultantId { get; set; }

    [XmlArray(ElementName = "subscription_product")]
    [XmlArrayItem("associate_end_user_id", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
    public List<int> Associates { get; set; }

    [XmlArray(ElementName = "product_id")]
    public List<int> Products { get; set; }
}

以下是用于反序列化的代码

public class SchemaReader : ISchemaReader
{

    public T Deserialise<T>(string input) where T : class
    {
        return Deserialise<T>(input, string.Empty);
    }

    public T Deserialise<T>(string input, string elementRootName) where T : class
    {
        return (T)Deserialise(input, typeof(T), elementRootName);
    }

    public object Deserialise(string input, Type objectType)
    {
        return Deserialise(input, objectType, string.Empty);
    }

    public object Deserialise(string input, Type objectType, string elementRootName)
    {
        var sr = new StringReader(input);

        // Create an XmlSerializer object to perform the deserialization
        var xs = string.IsNullOrEmpty(elementRootName)
                     ? new XmlSerializer(objectType)
                     : new XmlSerializer(objectType, new XmlRootAttribute {ElementName = elementRootName});

        return xs.Deserialize(sr);
    }
}

以下是我所拥有的单元测试,当它应该有3个时,会失败0。

    [TestMethod]
    public void DeserialiseMultipleAssociates()
    {
        // Arrange 
        var builder = new StringBuilder();
        builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        builder.Append(
            "<subscription_product consultant_end_user_id=\"4\" farm_id=\"6\" farm_name=\"Farm Name\" farmer_end_user_id=\"5\" subscription_expiry=\"2014-01-01\" subscription_id=\"7\">");
        builder.Append("<associate_end_user_id>1</associate_end_user_id>");
        builder.Append("<associate_end_user_id>2</associate_end_user_id>");
        builder.Append("<associate_end_user_id>3</associate_end_user_id>");
        builder.Append("<product_id>1</product_id>");
        builder.Append("<product_id>9</product_id>");
        builder.Append("</subscription_product>");

        var xml = builder.ToString();

        // Act
        var reader = new SchemaReader();
        var subscription = reader.Deserialise<Subscription>(xml);

        // Assert
        Assert.AreEqual(3, subscription.Associates.Count);
        Assert.AreEqual(2, subscription.Associates[1]);
    }

1 个答案:

答案 0 :(得分:1)

您应该使用包含关联和产品的xml结构作为列表元素。

<?xml version="1.0" "encoding=utf-8"?>
  <subscription_product consultant_end_user_id="4" farm_id="6" 
     farm_name="Farm Name"   
     farmer_end_user_id="5" 
     subscription_expiry="2014-01-01" 
     subscription_id="7">
    <associates>
        <associate_end_user_id>1</associate_end_user_id>
        <associate_end_user_id>2</associate_end_user_id>
        <associate_end_user_id>3</associate_end_user_id>
    </associates>
    <products>
        <product_id>8</product_id>
        <product_id>9</product_id>
        <product_id>10</product_id>
    </products>
  </subscription_product>