This is the way I'm currently getting data from XML, but it seems to be really inefficient, checking every localname in every iteration. How should I be doing it?
Here is a sample of the XML I am trying to parse, followed by my code.
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<result>
<properties type="array">
<property>
<last-account-review-at>2011-04-26 00:00:04</last-account-review-at>
<unit-balance type="integer">-104</unit-balance>
<daily-consumption type="decimal">10.8</daily-consumption>
<status>active</status>
<end-date></end-date>
<icp-number>0001234567RN602</icp-number>
<address>
<property-name nil="true"></property-name>
<flat-number>3</flat-number>
<suburb>Suburbia</suburb>
<street-number>21</street-number>
<region>Nether</region>
<street-name>Easy</street-name>
<district>Metropolis</district>
</address>
<start-date>2010-05-05</start-date>
<status-detail nil="true"></status-detail>
</property>
</properties>
<account-number>9001234567</account-number>
</result>
<version>1.0</version>
</hash>
I don't have any issues with the maintainability of my code, it's more that it seems like I shouldn't be comparing against so many things at every iteration.
public static class DataRetrieval
{
private static XmlNameTable _nt;
private static object _propertyElement;
private static object _unitBalanceElement;
private static object _dailyConsumptionElement;
private static object _statusElement;
static DataRetrieval()
{
_nt = new NameTable();
_propertyElement = _nt.Add("property");
_unitBalanceElement = _nt.Add("unit-balance");
_dailyConsumptionElement = _nt.Add("daily-consumption");
_statusElement = _nt.Add("status");
}
public static bool ParseCustomerData(string raw, out List<PropertyDetails> properties)
{
bool parsedOK = false;
properties = new List<PropertyDetails>();
PropertyDetails property = null;
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
settings.NameTable = _nt;
XmlReader reader = XmlReader.Create(new StringReader(raw), settings);
object localname;
bool continueReading = true;
int dataItemsRead = 0;
const int DataItemsToRead = 3;
try
{
while (continueReading)
{
if (reader.IsStartElement())
{
localname = reader.LocalName;
if (localname == _propertyElement)
{
if (property != null)
{
if (dataItemsRead == DataItemsToRead)
{
properties.Add(property);
dataItemsRead = 0;
}
else
{
break;
}
}
property = new PropertyDetails();
continueReading = reader.Read();
}
else if (localname == _unitBalanceElement)
{
property.UnitBalance = reader.ReadElementContentAsInt();
dataItemsRead++;
}
else if (localname == _dailyConsumptionElement)
{
property.DailyConsumption = reader.ReadElementContentAsDouble();
dataItemsRead++;
}
else if (localname == _statusElement)
{
if (property.SetStatus(reader.ReadElementContentAsString()))
{
dataItemsRead++;
}
}
else
{
continueReading = reader.Read();
}
}
else
{
continueReading = reader.Read();
}
}
}
catch (XmlException e)
{
Debug.WriteLine("XmlException: {0}", e.Message);
}
parsedOK = dataItemsRead == DataItemsToRead;
if ((property != null) && (parsedOK))
{
properties.Add(property);
}
return parsedOK;
}
}