user5814565
user5814565

Reputation:

Converting XML to objects with nested embeded objects

I have the following XML which has nested objects and when I want to deserialize the XML into the Steps class with the embedded list of Step objects, I have an error.

[XmlRoot(ElementName="comp")]
public class Comp 
{
    [XmlAttribute(AttributeName="ref")]
    public string Ref { get; set; }
    [XmlAttribute(AttributeName="dir")]
    public string Dir { get; set; }
}

[XmlRoot(ElementName="step")]
public class Step 
{
    [XmlElement(ElementName="comp")]
    public Comp Comp { get; set; }
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    [XmlElement(ElementName="step")]
    public Step Step { get; set; }
}

[XmlRoot(ElementName="steps")]
public class Steps 
{
    [XmlElement(ElementName="step")]
    public Step Step { get; set; }
}

My XML :

<steps>
  <step name="2.3  Upper">
    <step name="2.3.1 Upper">
      <comp ref="15.txt" dir="D:\test" />
      <comp ref="16.txt" dir="D:\test2" />
    </step>
    <step name="2.3.2  Upper" >
      <comp ref="19.txt" dir="D:\test" />
      <comp ref="29.txt" dir="D:\test2" />
    </step>
  </step>
</steps>

Update: new XML file for more nested step.

<steps>
  <step name="2.3  Upper">
    <step name="2.3.1 Upper">
      <step name="2.3.1.1 Upper">
        <comp ref="10.txt" dir="D:\test" />
      </step>
      <comp ref="15.txt" dir="D:\test" />
      <comp ref="16.txt" dir="D:\test2" />
    </step>
    <step name="2.3.2  Upper" >
      <comp ref="19.txt" dir="D:\test" />
      <comp ref="29.txt" dir="D:\test2" />
    </step>
  </step>
</steps>

May I ask your help how to get ride of the following error:

'Step': member names cannot be the same as their enclosing type

I am stuck on this error. I really appreciate for your helps.

Upvotes: 1

Views: 67

Answers (2)

user5814565
user5814565

Reputation:

I found out that one could use List<step> to have unlimited recursive as follows:

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class steps
{
    public script script { get; set; }
    [System.Xml.Serialization.XmlElementAttribute("step")]
    public List<step> step { get; set; }
}

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class step
{
    [System.Xml.Serialization.XmlElementAttribute("step")]
    public List<step> Step1 { get; set; }
    [System.Xml.Serialization.XmlElementAttribute("comp")]
    public List<comp> comp { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name { get; set; }
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class comp
{
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string @ref { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string dir { get; set; }
}

Upvotes: 0

Geoff James
Geoff James

Reputation: 3180

It's because in your Step class:

[XmlRoot(ElementName="step")]
public class Step 
{
    [XmlElement(ElementName="comp")]
    public Comp Comp { get; set; }
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    [XmlElement(ElementName="step")]
    public Step Step { get; set; } // <-- Here is your issue
}

You have a Step within a Step called Step (inception or what?!).

EDIT:

Better suggestion:

Remove the Steps class entirely - not needed.

Update your Step class, like so:

[XmlRoot(ElementName="step")]
public class Step 
{
    [XmlElement(ElementName="comp")]
    public Comp Comp { get; set; }
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    [XmlElement(ElementName="steps")]
    public List<Step> Steps { get; set; }
}

ADDITIONAL EDIT:

Your XML would then come out like this:

<steps>
    <step name="Step 1">
        <steps>
            <!-- 3 substeps in Step 1 -->
            <step name="Step 1 - 1st substep" ></step>
            <step name="Step 1 - 2nd substep" ></step>
            <step name="Step 1 - 3rd substep" >
                <steps>
                    <!-- The 3rd one has its own substep -->
                    <step name="Step 1 - 3rd substep - 1st substep"/>
                </steps>
            </step>
        </steps>
    </step>

    <step name="Step 2">
        <steps>
            <!-- Step 2 has 1 substep -->
            <step name="Step 2 - 1st substep"/>
        </steps>
    </step>

    <step name="Step 3">
        <!-- No substeps in here -->
    </step>
</steps>

Obviously your other elements/attributes within the step element would include your own, as in your example.

The main point is that the only thing that's changed in the Step class is that it can have its own list of Steps called Steps or Substeps (or whatever meaningful name you give).

Upvotes: 1

Related Questions