Search code examples
c#xmlxml-deserialization

c# - Deserialize XML w/ Nested Elements Using Attributes


I need to deserialize an XML file. So far i have been successful using the [XmlElement] attribute. It works great. Where i am tripping up is when it comes to a nested element. For example <root><level1><set1><data1>x</data1><data2>y</data2></set1>.....</root> and I only wish to capture data2 inside of set 1. I've experimented with [XmlArray] and [XmlArrayItem] but havent had much luck. I could be wrong but I didnt think a List would be appropriate since I only want one value for the class attribute. There is a bettere example bellow more specific to my problem. In it i would be concerned with capturing the <NAME> element inside of <H_DATA_1> that is nested in <HEADER> I have been successful in capturing what I need from the 1st <METADATA> inside of <PRODUCTION_SET> as well as pulling what i need from the 2nd <METADATA> inside of <PRODUCING_ENTITY> however my methods do not seem to be able to handle the additional nesting inside of the header tag.

XML

<PRODUCTION_SET>
    <METADATA>
        <M_DATA_1>X</M_DATA_1>
        <M_DATA_2>Y</M_DATA_2>
        <M_DATA_3>Z</M_DATA_3>
    </METADATA>
    <PRODUCING_ENTITY>
        <METADATA>
            <PM_Data_1>X<PM_Data_1>
            <PM_Data_2>Y<PM_Data_2>
        </Metadata>
        <HEADER>
            <H_DATA_1>
                <NAME>I NEED THIS NAME</NAME>
            </H_DATA_1>
            <H_DATA_2>
                <NAME>I ALSO NEED THIS NAME</NAME>
                <CODE>DO NOT WANT THIS CODE</CODE>
            </H_DATA_2>
            <H_DATA_3>
                <NAME>I DO NOT NEED THIS NAME</NAME>
            </H_DATA_3>
        </HEADER>
    </PRODUCING_ENTITY>
    <PRODUCING_ENTITY>
    .
    .
    .
    </PRODUCING_ENTITY>
.
.
.
.
</PRODUCING_SET>

CLASS

[Serializable()]
[XmlRoot("PRODUCTION_SET")]
public class ProductionSet
{
    [XmlElement("METADATA")]
    public List<Metadata> Metadata { get; set; }

    [XmlElement("PRODUCING_ENTITY")]
    public List<Producing_Entity> ProducingEntity { get; set; }

}

public class Metadata
{
    [XmlElement("M_DATA_1")]
    public string mData1 { get; set; }
    [XmlElement("M_DATA_2")]
    public string mdata2 { get; set; }
}

public class Producing_Entity
{
    [XmlElement("METADATA")]
    public List<ProdMeta> ProdMeta { get; set; }

    [XmlElement("HEADER")]
    public List<Header> Header { get; set; }


}

public class ProdMeta
{
    [XmlElement("PM_DATA_1")]
    public string pmData1{ get; set; }

}


public class Header
{
    [XmlElement("H_DATA1")]
    [XmlElement("NAME")]
    public string H_DATA1_Name { get; set; }


    [XmlElement("H_DATA2")]
    [XmlElement("NAME")]
    public string H_DATA2_Name { get; set; }


}

Solution

  • You will need one step more:

    public class Header
    {
        [XmlElement("H_DATA1")]
        public H_DATA1 HData1 { get; set; }
        ....
    }
    
    public class H_DATA1 
    {
        [XmlElement("NAME")]
        public String Name { get; set; }
    }