Reputation: 5689
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
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;
define in your constructor of element
initialization of subElems
and Attributes
like
public element()
{
this.subElems = new List<element>();
this.Attributes = new List<attribute>();
}
Change your field declaration to
private List<element> SubElems = new List<element>();
private List<attribute> attributes = new List<attribute>();
Upvotes: 2