I’m writing an XML parser in C# to extract a lot (many files, coming to over 200GB of data) of entries stored in xml form. I’m using Linq to XML to parse the files and get all the information into objects I created for them (14 objects; some objects contain lists of objects which contain lists of objects — It’s a lot of data).
The problem I’m running into is that some entries may have zero or more instances of a certain object. In a database context, this is no problem but I have no idea how to tell my program that if it can’t find the appropriate object under the tag that it should just create an empty/default one instead. Running the program gives me a “sequence contains no elements” error and exception handling doesn’t work since the program just exits the query when it finds an empty listing instead of ignoring it.
How do I go about handling zero-or-more cases in the linq-to-xml query?
the definitions for the objects in question are:
<!ELEMENT prior-registration-applications (other-related-in* , prior-registration-application*)>
<!ELEMENT other-related-in (#PCDATA)>
<!ELEMENT prior-registration-application (relationship-type? , number?)>
The code I’m getting the problem at is this:
priorRegistrationApplications = (
from q in e.Elements("prior-registration-applications")
select new PriorRegistrationApplications(
(string)q.Element("other-related-in"),
(from w in q.Elements("prior-registration-application")
select new PriorRegistrationApplication(
(string)w.Element("relationship-type"),
convertToInt((string)w.Element("number")))
).ToList()
)
).First(), //end prior-applications
The object definition for PriorRegistrationApplications is:
class PriorRegistrationApplications
{
public string other_related_in; //only one appears, regardless of number of applications it seems.
List<PriorRegistrationApplication> priorRegistrationApplications;
public PriorRegistrationApplications(string other_related_in, List<PriorRegistrationApplication> priorRegistrationApplications)
{
this.other_related_in = other_related_in;
this.priorRegistrationApplications = priorRegistrationApplications;
}
and for PriorRegistrationApplication:
class PriorRegistrationApplication
{
public PriorRegistrationApplication() {
relationship_type = "";
number = 0;
}
public PriorRegistrationApplication(string relationship_type, int number)
{
this.relationship_type = relationship_type;
this.number = number;
}
It’s not entirely clear where the code is failing (or why you have extraneous parentheses around your
ToListcall, or why you’re callingToListat all) but you could consider simply changing yourFirst()call toFirstOrDefault(). Then if that returnsnull, there were no elements. That’s not the same as creating a “default” one, but you could always use:if you really want. (Do you really have to have an empty object here?)
Also note that this:
not only violates naming conventions, but would probably be more simply written as: