patterncsharpMinor
There has to be a better way of parsing XML in C# than what I'm doing
Viewed 0 times
whatthanwaydoingbetterxmlhasparsingthere
Problem
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.
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 properties)
{
bool parsedOK = false;
properties = new List();
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
{
Here is a sample of the XML I am trying to parse, followed by my code.
2011-04-26 00:00:04
-104
10.8
active
0001234567RN602
3
Suburbia
21
Nether
Easy
Metropolis
2010-05-05
9001234567
1.0
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 properties)
{
bool parsedOK = false;
properties = new List();
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
{
Solution
You could try using
It would also help to see an example of the
EDIT:
You could do this (
Note: I didn't include any error checking, just wanted to show some possibilities.
XDocument instead. It would also help to see an example of the
xml you're trying to parse in order to properly suggest a refactoring of your code. EDIT:
You could do this (
XDocument + LINQ): string sXml = @"
2011-04-26 00:00:04
-104
10.8
active
0001234567RN602
3
Suburbia
21
Nether
Easy
Metropolis
2010-05-05
9001234567
1.0
";
var xml = XDocument.Parse(sXml);
var r = from x in xml.Descendants("property")
select new
{
unitBalance = x.Element("unit-balance").Value,
dailyConsumption = x.Element("daily-consumption").Value,
status = x.Element("status").Value
};
this._propertyElement = xml.Descendants("property");
this._unitBalanceElement = r.ElementAt(0).unitBalance;
this._dailyConsumptionElement = r.ElementAt(0).dailyConsumption;
this._statusElement = r.ElementAt(0).status;Note: I didn't include any error checking, just wanted to show some possibilities.
Code Snippets
string sXml = @"<?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>";
var xml = XDocument.Parse(sXml);
var r = from x in xml.Descendants("property")
select new
{
unitBalance = x.Element("unit-balance").Value,
dailyConsumption = x.Element("daily-consumption").Value,
status = x.Element("status").Value
};
this._propertyElement = xml.Descendants("property");
this._unitBalanceElement = r.ElementAt(0).unitBalance;
this._dailyConsumptionElement = r.ElementAt(0).dailyConsumption;
this._statusElement = r.ElementAt(0).status;Context
StackExchange Code Review Q#2826, answer score: 8
Revisions (0)
No revisions yet.