1

I am retrieving xml data from an web api and deserializing the data into objects.:

<Result>
  <VendorInfo xml:lang="xx">
    <Vendor vname="A" cpe="B">
      <Product pname="C" cpe="D"/>
    </Vendor>
    <Vendor vname="E" cpe="F">
      <Product pname="G" cpe="H"/>
    </Vendor>
    <Vendor vname="I" cpe="J">
      <Product pname="K" cpe="L"/>
      <Product pname="M" cpe="N"/>
    </Vendor>
  </VendorInfo>
  <Status keyword="hoge" feed="bar"/>
</Result>

My current code is this:

[XmlRoot(ElementName = "Product")]
public class Product
{
    [XmlAttribute(AttributeName = "pname")]
    public string Pname { get; set; }
    [XmlAttribute(AttributeName = "cpe")]
    public string Cpe { get; set; }
}

[XmlRoot(ElementName = "Vendor")]
public class Vendor
{
    [XmlArrayItem(ElementName = "Product")]
    public List<Product> Product { get; set; }
    [XmlAttribute(AttributeName = "vname")]
    public string Vname { get; set; }
    [XmlAttribute(AttributeName = "cpe")]
    public string Cpe { get; set; }
}

[XmlRoot(ElementName = "VendorInfo")]
public class VendorInfo
{
    [XmlElement(ElementName = "Vendor")]
    public List<Vendor> Vendor { get; set; }
    [XmlAttribute(AttributeName = "lang")]
    public string Lang { get; set; }
}

[XmlRoot(ElementName = "Status")]
public class Status
{
    [XmlAttribute(AttributeName = "feed")]
    public string Feed { get; set; }
    [XmlAttribute(AttributeName = "keyword")]
    public string Keyword { get; set; }
}

[XmlRoot(ElementName = "Result")]
public class Result
{
    [XmlElement(ElementName = "VendorInfo")]
    public VendorInfo VendorInfo { get; set; }
    [XmlElement(ElementName = "Status")]
    public Status Status { get; set; }
}

But, This code does not working correctly. Only first 2 Vendor elements are deserialized, Product element is not deserialized. What am i doing wrong?

best regards

tat
  • 11
  • 1
  • https://stackoverflow.com/questions/8254264/how-do-i-set-xmlarrayitem-element-name-for-a-listcustom-implementation ? – aybe May 14 '18 at 17:04
  • Change From : [XmlArrayItem(ElementName = "Product")] To : [XmlElement(ElementName = "Product")] – jdweng May 14 '18 at 18:01

1 Answers1

0

You have few things to be taken care.

Make only one element XmlRoot. Refer below link and search for "Controlling Serialization of Classes Using XmlRootAttribute and XmlTypeAttribute".

https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes

Here in your case, the "Result" class is root.

Make rest all XmlType.

In the vendor class instead of "XmlArrayItem", make it just "XmlElement".

Here is the working code.

    [XmlType("Product")]
    public class Product
    {
        [XmlAttribute(AttributeName = "pname")]
        public string Pname { get; set; }
        [XmlAttribute(AttributeName = "cpe")]
        public string Cpe { get; set; }
    }

    [XmlType("Vendor")]
    public class Vendor
    {
        [XmlElement(ElementName = "Product")]
        public List<Product> Product { get; set; }
        [XmlAttribute(AttributeName = "vname")]
        public string Vname { get; set; }
        [XmlAttribute(AttributeName = "cpe")]
        public string Cpe { get; set; }
    }

    [XmlType("VendorInfo")]
    public class VendorInfo
    {
        [XmlElement(ElementName = "Vendor")]
        public List<Vendor> Vendor { get; set; }
        [XmlAttribute(AttributeName = "xml:lang")]
        public string Lang { get; set; }
    }

    [XmlType("Status")]
    public class Status
    {
        [XmlAttribute(AttributeName = "feed")]
        public string Feed { get; set; }
        [XmlAttribute(AttributeName = "keyword")]
        public string Keyword { get; set; }
    }

    [XmlRoot(ElementName = "Result")]
    public class Result
    {
        [XmlElement(ElementName = "VendorInfo")]
        public VendorInfo VendorInfo { get; set; }
        [XmlElement(ElementName = "Status")]
        public Status Status { get; set; }
    }
Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • XmlRoot is correct. The only thing that needs changing is the XmlArrayItem. – jdweng May 14 '18 at 23:35
  • Yes....but the documentation link which I provided clearly says not to use .... XmlRoot for more than one class.... – Pavan Chandaka May 14 '18 at 23:38
  • First the documentation say XmlRootAtrribute and not XmlRoot. Second I have used XmlRoot lots of times are more than one class and it works. Microsoft Webpages and known to have lots of errors. Microsoft probably hired Technical Writers to write those webpages who have never programmed. Don't believe everything that Microsoft says. – jdweng May 15 '18 at 01:12