Imesh Chandrasiri
Imesh Chandrasiri

Reputation: 5689

How to check if a node has child elements

I'm writing an xml reader where a class structure will represent the data from an xml file..

for an example:

<catalog>
<book id="bk101">
  <author>Gambardella, Matthew</author>
  <title>XML Developer's Guide</title>
  <genre>Computer</genre>
  <price>44.95</price>
  <publish_date>2000-10-01</publish_date>
  <description>An in-depth look at creating applications 
  with XML.</description>
</book>
</catalog> 

how can I find that a node contains child nodes! I used the isempty element method! but I get an exception.

 public element read(XmlReader xml)
    {
        element elem = new element();
        while (xml.Read())
        {
            if (xml.IsEmptyElement)
            {
                elem.ElemName = xml.Name;
                if (xml.HasAttributes)
                {
                    for (int i = 0; i <= xml.AttributeCount; i++)
                    {
                        xml.MoveToNextAttribute();
                        attribute attrib = new attribute();
                        attrib.AttName = xml.Name;
                        attrib.AttValue = xml.Value;
                        elem.Attributes.Add(attrib);
                    }
                }
                return elem;
            }
            else
            {
                elem.ElemName = xml.Name;

                if (xml.HasAttributes)
                {
                    for (int i = 1; i < xml.AttributeCount; i++)
                    {
                        xml.MoveToNextAttribute();
                        attribute attrib = new attribute();
                        attrib.AttName = xml.Name;
                        attrib.AttValue = xml.Value;
                        elem.Attributes.Add(attrib);
                    }
                }

                elem.subElems.Add(read(xml)); -> Object reference not set to an instance of an object.
                return elem;
            }
        }
        return elem;
    }

I use two classes. one called element and one called attributes. what I do here is I go line by line and when I find an element I create an element type object. then I check whether that element contains any attribute. if so, I create attribute type objects for the attributes I encounter and add them to the attribute list which is in the element object. then I check for sub elements and if I find any, I add them as separate element objects to a list in the main element object.

  class element
{
    private String elemName;

    public String ElemName
    {
        get { return elemName; }
        set { elemName = value; }
    }
    private String elemValue;

    public String ElemValue
    {
        get { return elemValue; }
        set { elemValue = value; }
    }
    private List<attribute> attributes;

    internal List<attribute> Attributes
    {
        get { return attributes; }
        set { attributes = value; }
    }

    private List<element> SubElems;

    internal List<element> subElems
    {
        get { return SubElems; }
        set { SubElems = value; }
    }

}

class attribute
{
    private String Name;

    public String AttName
    {
        get { return Name; }
        set { Name = value; }
    }
    private String value;

    public String AttValue
    {
        get { return this.value; }
        set { this.value = value; }
    }
}

Upvotes: 0

Views: 6321

Answers (1)

Ilya Ivanov
Ilya Ivanov

Reputation: 23646

When you create element elem = new element(); you never assign values to subElems, only to elem.ElemName = xml.Name. So as result you get NullReferenceException because on subElems you have null after object creation. I have refactored your code (Note that I don't know anything about element class)

public element read(XmlReader xml)
{
    element elem = new element();
    while (xml.Read())
    {
        elem.ElemName = xml.Name;
        if (xml.HasAttributes)
        {
            for (int i = 0; i <= xml.AttributeCount; i++)
            {
                xml.MoveToNextAttribute();
                attribute attrib = new attribute();
                attrib.AttName = xml.Name;
                attrib.AttValue = xml.Value;
                elem.Attributes.Add(attrib);
            }
        }
        if (xml.IsEmptyElement)
        {   
            return elem;
        }
        else
        {
            elem.subElems = new List<element>(); //create new List of subelements
            elem.subElems.Add(read(xml)); 
            return elem;
        }
    }
    return elem;

OR

define in your constructor of element initialization of subElems and Attributes like

public element()
{
    this.subElems = new List<element>();
    this.Attributes = new List<attribute>();
}

OR

Change your field declaration to

private List<element> SubElems = new List<element>();
private List<attribute> attributes = new List<attribute>();

Upvotes: 2

Related Questions