How do I read a XML file (XMLfile.xml) using LINQ in a previously made file in the root of a ASP.net program. Each Element exist in the XML file I have already created (see below for an excerpt).
XDocument xmlElements = XDocument.Parse(System.IO.File.ReadAllText(Server.MapPath("XMLfile.xml")));
var elements = from data in xmlElements.Descendants("/NewDataSet/Table")
select new
{
Number0 = (int)data.Element("Number"),
Name0 = (string)data.Element("Name"),
a0 = (double)data.Element("a"),
e0 = (double)data.Element("e"),
i0 = (double)data.Element("i"),
N0 = (double)data.Element("N"),
w0 = (double)data.Element("w"),
Pyrs0 = (double)data.Element("Pyrs"),
mm0 = (double)data.Element("mm"),
MA0 = (double)data.Element("MA0")
};
foreach (var element in elements)
{
m = m + 1;
num[m] = element.Number0;
nam[m] = element.Name0;
a1[m] = element.a0;
ecc[m] = element.e0;
i[m] = element.i0;
N[m] = element.N0;
w[m] = element.w0;
Pyrs[m] = element.Pyrs0;
mm[m] = element.mm0;
MA0[m] = element.MA0;
}
XMLfile.xml
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Table>
<Number>1</Number>
<Name>Ceres</Name>
<a>2.7681117</a>
<e>0.0757544</e>
<i>10.59166</I>
<N>80.3218024</N>
<w>72.73324</w>
<Pyrs>4.61</Pyrs>
<mm>0.2140072</mm>
<MA0>181.38143</MA0>
</Table>
<Table>
<Number>2</Number>
<Name>Pallas</Name>
<a>2.7723622</a>
<e>0.2310236</e>
<i>34.84095</i>
<N>173.0882785</N>
<w>309.98943</w>
<Pyrs>4.62</Pyrs>
<mm>0.2135153</mm>
<MA0>163.60434</MA0>
</Table>
...
</NewDataSet>
What has worked for me is the extension method XPathSelectElements. As in:
var elements = from data in xmlElements.XPathSelectElements("/NewDataSet/Table")
select new
{
Number0 = (int)data.Element("Number"),
Name0 = (string)data.Element("Name"),
a0 = (double)data.Element("a"),
e0 = (double)data.Element("e"),
i0 = (double)data.Element("i"),
N0 = (double)data.Element("N"),
w0 = (double)data.Element("w"),
Pyrs0 = (double)data.Element("Pyrs"),
mm0 = (double)data.Element("mm"),
MA0 = (double)data.Element("MA0")
};
The code below is XML Linq like you requests. XML is case sensitive so you need to change the closing tag "I" to "i". I tested the code below and it works. If you have a string instead of the file then change "Load" to "Parse".
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Table").Select(x => new
{
number = (int)x.Element("Number"),
name = (string)x.Element("Name"),
a = (double)x.Element("a"),
e = (double)x.Element("e"),
i = (double)x.Element("i"),
n = (double)x.Element("N"),
w = (double)x.Element("w"),
pyrs = (double)x.Element("Pyrs"),
mm = (double)x.Element("mm"),
ma0 = (double)x.Element("MA0")
}).ToList();
}
}
}
Related
Hello there C# enthusiast!
I am trying to create an XML file based on the elements subtraction of another two xml files ( the difference in value of elements)
For example:
The Source Xml files
Sought output:
Expected output
I did a quick research and found that there is a lib for XML content difference but none that fulfill this
functionality.
I know this can be solved by System.xml class , but I don't know exactly how to start.
Any help is appreciated.
XML Text Sample:
<?xml version="1.0" encoding="utf-8"?>
<Report>
<Project>
<Name>P1</Name>
<Runs>10</Runs>
<Errors>5</Errors>
<Successful>5</Successful>
</Project>
.
. Multiple Projects exists here
.
<Project>
<Name>P2</Name>
<Runs>12</Runs>
<Errors>3</Errors>
<Successful>9</Successful>
</Project>
<Timestamp>
<Year>2020</Year>
<Month>6</Month>
<Day>8</Day>
<Hour>12</Hour>
</Timestamp>
</Report>
Try xml linq. I assumed you had same Projects in both input and output files. If not you will need a left outer join. :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication3
{
class Program
{
const string INPUT_FILENAME_1 = #"c:\temp\test.xml";
const string INPUT_FILENAME_2 = #"c:\temp\test1.xml";
const string OUTPUT_FILENAME = #"c:\temp\test.xml2";
static void Main(string[] args)
{
XDocument doc1 = XDocument.Load(INPUT_FILENAME_1);
DateTime date1 = doc1.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
XDocument doc2 = XDocument.Load(INPUT_FILENAME_2);
DateTime date2 = doc2.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
string ident = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Report></Report>";
XDocument outputDoc = XDocument.Parse(ident);
XElement outputReport = outputDoc.Root;
XElement oldReport;
XElement newReport;
TimeSpan deltaTime;
if (date2 > date1)
{
newReport = doc2.Root;
oldReport = doc1.Root;
deltaTime = date2.Subtract(date1);
}
else
{
newReport = doc1.Root;
oldReport = doc2.Root;
deltaTime = date1.Subtract(date2);
}
var groups = (from n in newReport.Elements("Project")
join o in oldReport.Elements("Project")
on (string)n.Element("Name") equals (string)o.Element("Name")
select new { oldProj = o, newProj = n }
).ToList();
foreach (var group in groups)
{
XElement difference = new XElement("Project", new object[] {
new XElement("Name", (string)group.newProj.Element("Name")),
new XElement("Runs", (int)group.newProj.Element("Runs") - (int)group.oldProj.Element("Runs")),
new XElement("Errors", (int)group.newProj.Element("Errors") - (int)group.oldProj.Element("Errors")),
new XElement("Successful", (int)group.newProj.Element("Successful") - (int)group.oldProj.Element("Successful"))
});
outputReport.Add(difference);
}
XElement newTime = new XElement("Timestamp", new object[] {
new XElement("Year", 0),
new XElement("Month", 0),
new XElement("Day", deltaTime.Days),
new XElement("Hour", deltaTime.Hours)
});
outputReport.Add(newTime);
outputDoc.Save(OUTPUT_FILENAME);
}
}
}
I have tried for hours on this.
I need to access the data in the top section to get the SenderCode
Then I need to step through all of the RecipientDeliveries sections and get the RecipientCode then the name/address info for that one.
To try and get the deliveries I have tried this (along with about 100 variations).
No error, but no data is returned ("Enumeration yielded no results")
In the below what I need to do if have code that steps through each of the Recipient sections, grab the 'RecipientCode' for that section and then get the various names and addresses.
I can get the specific SenderCode by doing this:
string xmlText;
using (var memoryStream = new MemoryStream())
{
ASN_Blob.DownloadToStream(memoryStream);
xmlText = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
var document = XDocument.Parse(xmlText);
var aw2 = "http://www.omnicare.com/schema/AdvancedShippingNotices.xsd";
var SenderCode = document.Descendants(XName.Get("SenderCode",aw2)).First().Value;
But keep running into a wall past that.
Here is the XML I need to decode:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:AdvancedShippingNotices xmlns:ns0="http://www.omnicare.com/schema/AdvancedShippingNotices.xsd">
<ns0:ASNID>4129114</ns0:ASNID>
<ns0:CourierID>4SAMEDAY</ns0:CourierID>
<ns0:SenderCode>598</ns0:SenderCode>
<ns0:SenderNameAndAddress>
<ns0:Name>Customer of San Diego</ns0:Name>
<ns0:Address>
<ns0:Line1>5601 Oberlin Drive, Suite 124</ns0:Line1>
<ns0:CityTownOrLocality>San Diego</ns0:CityTownOrLocality>
<ns0:StateOrProvince>CA</ns0:StateOrProvince>
<ns0:PostalCode>92121-3709</ns0:PostalCode>
</ns0:Address>
</ns0:SenderNameAndAddress>
<ns0:RecipientDeliveries>
<ns0:Recipient>
<ns0:RecipientCode>1019</ns0:RecipientCode>
<ns0:RecipientNameAndAddress>
<ns0:Name>VILLAGE SQUARE HEALTHCARE CTR</ns0:Name>
<ns0:Address>
<ns0:Line1>1586 W SAN MARCOS BLVD</ns0:Line1>
<ns0:CityTownOrLocality>SAN MARCOS</ns0:CityTownOrLocality>
<ns0:StateOrProvince>CA</ns0:StateOrProvince>
<ns0:PostalCode>92069</ns0:PostalCode>
</ns0:Address>
</ns0:RecipientNameAndAddress>
<ns0:Deliveries>
<ns0:Delivery>
<ns0:DeliveryID>8930798-5</ns0:DeliveryID>
<ns0:DeliveryType>ROUTE</ns0:DeliveryType>
<ns0:DeliveryRoute>R0130</ns0:DeliveryRoute>
<ns0:ToteID>S5-278</ns0:ToteID>
<ns0:NursingStation>2</ns0:NursingStation>
</ns0:Delivery>
</ns0:Deliveries>
</ns0:Recipient>
<ns0:Recipient>
<ns0:RecipientCode>20366</ns0:RecipientCode>
<ns0:RecipientNameAndAddress>
<ns0:Name>OAKMONT OF ESCONDIDO HILLS</ns0:Name>
<ns0:Address>
<ns0:Line1>3012 BEAR VALLEY PKWY</ns0:Line1>
<ns0:CityTownOrLocality>ESCONDIDO</ns0:CityTownOrLocality>
<ns0:StateOrProvince>CA</ns0:StateOrProvince>
<ns0:PostalCode>92025</ns0:PostalCode>
</ns0:Address>
</ns0:RecipientNameAndAddress>
<ns0:Deliveries>
<ns0:Delivery>
<ns0:DeliveryID>8930798-4</ns0:DeliveryID>
<ns0:DeliveryType>ROUTE</ns0:DeliveryType>
<ns0:DeliveryRoute>R0130</ns0:DeliveryRoute>
<ns0:ToteID>F1-101</ns0:ToteID>
<ns0:NursingStation>AL</ns0:NursingStation>
</ns0:Delivery>
</ns0:Deliveries>
</ns0:Recipient>
</ns0:RecipientDeliveries>
</ns0:AdvancedShippingNotices>
UPDATE:
There is a good working solution that I accepted. But I also came up with this which was working also. I am posting it here just in case it helps somebody else.
//go get the file pointed to by the message in the Blob Storage
CloudBlockBlob ASN_Blob = getBlockBlobByName(fileName, storageAccount, blobContainerName);
string xmlText;
using (var memoryStream = new MemoryStream())
{
ASN_Blob.DownloadToStream(memoryStream);
xmlText = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
//use a dataset
DataSet Ds = new DataSet();
System.IO.StringReader xmlSR1 = new System.IO.StringReader(xmlText);
Ds.ReadXml(xmlSR1);
//get all of the individual totes or items
var Deliveries = (from rec in Ds.Tables["Delivery"].AsEnumerable()
select new
{
fir = rec[0],
sec = rec[1],
thi = rec[2],
forth = rec[3],
nursingStation = rec[4],
delId = Convert.ToInt16( rec[5])
}).ToArray();
//combine them -- needs to be expanded still
var comb3 = (from recipient in Ds.Tables["Recipient"].AsEnumerable()
join recName in Ds.Tables["RecipientNameAndAddress"].AsEnumerable() on recipient[1] equals recName[1]
join address in Ds.Tables["Address"].AsEnumerable() on recipient[1] equals address[6]
select new
{
recipientName = recName[0],
receipientCode = recipient[0],
add1 = address[0],
Id = recName[1]
}
).ToArray();
//prove out that everythying is there
foreach (var stop in comb3)
{
Console.WriteLine($"name: {stop.recipientName} address: {stop.add1}");
//get all the items for this stop
var items = (from i in Deliveries where i.delId == Convert.ToInt16(stop.Id) select i).ToArray();
foreach (var tote in items)
{
Console.WriteLine($"DeliveryId: {tote.fir} Type:{tote.sec} Nursing Station: -{tote.nursingStation}-");
}
}
Using xml linq (XDocument) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns0 = doc.Root.GetNamespaceOfPrefix("ns0");
XElement sender = doc.Descendants(ns0 + "SenderNameAndAddress").FirstOrDefault();
string[] senderAddress = sender.Descendants(ns0 + "Address").Elements().Select(x => (string)x).ToArray();
XElement recipientDeliveries = doc.Descendants(ns0 + "RecipientDeliveries").FirstOrDefault();
var results = recipientDeliveries.Elements(ns0 + "Recipient").Select(x => new
{
name = (string)x.Descendants(ns0 + "Name").FirstOrDefault(),
address = x.Descendants(ns0 + "Address").Elements().Select(y => (string)y).ToArray(),
deliveryID = (string)x.Descendants(ns0 + "DeliveryID").FirstOrDefault(),
deliveryType = (string)x.Descendants(ns0 + "DeliveryType").FirstOrDefault(),
deliveryRoute = (string)x.Descendants(ns0 + "DeliveryRoute").FirstOrDefault(),
toteID = (string)x.Descendants(ns0 + "ToteID").FirstOrDefault(),
nursingStation = (string)x.Descendants(ns0 + "NursingStation").FirstOrDefault()
}).ToList();
}
}
}
Try something like this...works on my machine after creating an xml file from your snippet.
XElement dataFromXML = XElement.Parse(xmlText);
XNamespace aw = "http://www.xxxxxx.com/schema/AdvancedShippingNotices.xsd";
var textSegs = dataFromXML.Descendants(aw + "RecipientDeliveries");
IEnumerable<XElement> textSegs = dataFromXML.Descendants(aw + "RecipientDeliveries");
var recipients = textSegs.Descendants(aw + "RecipientCode");
var address = recipients.Select(x => x.NextNode).FirstOrDefault();
I would also recommend in the future to post a small but valid xml snippet, saves those helping you from having to do so.
I have below XML.
<subscription>
<subscription_add_ons type="array">
<subscription_add_on>
<add_on_code>premium_support</add_on_code>
<name>Premium Support</name>
<quantity type="integer">1</quantity>
<unit_amount_in_cents type="integer">15000</unit_amount_in_cents>
<add_on_type>fixed</add_on_type>
<usage_percentage nil="true"></usage_percentage>
<measured_unit_id nil="true"></measured_unit_id>
</subscription_add_on>
</subscription_add_ons>
My XMLParse function
public XNode GetXmlNodes(XElement xml, string elementName)
{
List<string> addOnCodes= new List<string>();
//elementName = "subscription_add_ons ";
var addOns = xml.DescendantNodes().Where(x => x.Parent.Name == elementName).FirstOrDefault();
foreach (XNode addOn in addOns)
{
//Needed to do something like this
/*var len = "add_on_code".Length + 2;
var sIndex = addOn.ToString().IndexOf("<add_on_code>") + len;
var eIndex = addOn.ToString().IndexOf("</add_on_code>");
var addOnCode = addOn.ToString().Substring(sIndex, (eIndex - sIndex)).Trim().ToLower();
addOnCodes.Add(addOnCode);*/
}
As mentioned in comments by #JonSkeet, I updated my snippet as below.
var addOns = xml.Descendants(elementName).Single().Elements();
foreach (XNode addOn in addOns)
{
/*addon = {<subscription_add_on>
<add_on_code>premium_support</add_on_code>
<name>Premium Support</name>
<quantity type="integer">1</quantity>
<unit_amount_in_cents type="integer">15000</unit_amount_in_cents>
<add_on_type>fixed</add_on_type>
<usage_percentage nil="true"></usage_percentage>
<measured_unit_id nil="true"></measured_unit_id>
</subscription_add_on>} */
//how to get the addOnCode node value ?
var addOnCode = string.Empty;
addOnCodes.Add(addOnCode);
}
But what I need is from the passed XML, get all the nodes of type subscription_add_on then get the value contained in add_on_code & add it to string collection.
Or in general get the value of node by passing type ? Tried with the available methods coming from VS Intellisense but not getting the exact method that can do this?
Thanks!
Here is solution with Xml Linq (XDOCUMENT) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication107
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("subscription_add_on").Select(x => new
{
add_on_code = (string)x.Element("add_on_code"),
name = (string)x.Element("name"),
quantity = (int)x.Element("quantity"),
amount = (int)x.Element("unit_amount_in_cents"),
add_on_type = (string)x.Element("add_on_type")
}).ToList();
}
}
}
I have the following xml:
<?xml version="1.0" encoding="utf-8"?>
<RootData>
<PassResult>
<FirstOne>P1</FirstOne>
<SecondOne>P2</SecondOne>
<IsMale>false</IsMale>
</PassResult>
<TestResult>
<MarkOne>100</MarkOne>
<MarkTwo>50</MarkTwo>
<Slope>30</Slope>
</TestResult>
<ToneTestResult>
<TotalTime>2</TotalTime>
<CorrectPercentage>90</CorrectPercentage>
</ToneTestResult>
<QuestionnaireResult Version="1">
<Question Id="50">
<Answer Id="B" />
</Question>
<Question Id="60">
<Answer Id="A" />
</Question>
</QuestionnaireResult>
</RootData>
I have the following code which is not at all looking a good one. Lots of repeatative link queries.
How can I refactor this code in a more structured way to fill "OutputData" object. I do not want to change it to XmlSerializer now :-(.
Sample code:
// Gets the root element decendants
var elementRootData = xDocument.Descendants("RootData");
var xElements = elementRootData as IList<XElement> ?? elementRootData.ToList();
// Read first leaf node "ProfileResult"
var passResult = from xElement in xElements.Descendants("PassResult")
select new
{
FirstOne = xElement.Element("FirstOne").GetValue(),
SecondOne = xElement.Element("SecondOne").GetValue(),
IsMale = xElement.Element("IsMale").GetValue()
};
// Read second leaf note
var testResult = from xElement in xElements.Descendants("TestResult")
select new
{
MarkOne = xElement.Element("MarkOne").GetValue(),
MarkTwo = xElement.Element("MarkTwo").GetValue(),
Slope = xElement.Element("Slope").GetValue()
};
// Update OutputData object
var parseOutputData = new OutputData();
foreach (var result in passResult)
{
parseOutputData.FirstOne = result.FirstOne;
parseOutputData.SecondOne = result.SecondOne;
parseOutputData.IsMale = result.IsMale.Equals("True");
}
foreach (var result in testResult)
{
parseOutputData.MarkOne = double.Parse(result.MarkOne);
parseOutputData.MarkTwo = double.Parse(result.MarkTwo);
parseOutputData.Slope = double.Parse(result.Slope);
}
I have to write some more code like this to fill other elements data like ToneTestResult, QuestionnaireResult etc.
Can someone suggest with a sample code?
Best regards,
Given your XML is tiny, you probably don't have to worry too much about performance. You can just do the whole thing in one go, making use of the built in explicit conversions:
var data = new OutputData
{
FirstOne = (string) doc.Descendants("FirstOne").Single(),
SecondOne = (string) doc.Descendants("SecondOne").Single(),
IsMale = (bool) doc.Descendants("IsMale").Single(),
MarkOne = (double) doc.Descendants("MarkOne").Single(),
MarkTwo = (double) doc.Descendants("MarkTwo").Single(),
Slope = (double) doc.Descendants("Slope").Single()
};
As an aside, Descendants will never return anything implementing IList<XElement>, so you can definitely remove that.
Try XML Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var root = doc.Elements("RootData").Select(x => new
{
passResults = x.Elements("PassResult").Select(y => new
{
firstOne = (string)y.Element("FirstOne"),
secondOne = (string)y.Element("SecondOne"),
isMale = (Boolean)y.Element("IsMale")
}).FirstOrDefault(),
testResult = x.Elements("TestResult").Select(y => new {
markOne = (int)y.Element("MarkOne"),
markTwo = (int)y.Element("MarkTwo"),
slope = (int)y.Element("Slope")
}).FirstOrDefault(),
toneTestResult = x.Elements("ToneTestResult").Select(y => new {
totalTime = (int)y.Element("TotalTime"),
correctPecentage = (int)y.Element("CorrectPercentage")
}).FirstOrDefault(),
questionnaireResult = x.Elements("QuestionnaireResult").Elements("Question").Select(y => new {
question = (int)y.Attribute("Id"),
answer = (string)y.Descendants("Answer").FirstOrDefault().Attribute("Id")
}).ToList(),
}).FirstOrDefault();
}
}
}
I'm trying to read an XML file and parse its content, but I'm having trouble extracting parameters from the file.
The XML file I'm trying to parse looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<register_map>
<Register ID="1" Index="0x100000" DataType="0x0007" ObjectType="0x07" Name="Device Type"/>
<Register ID="2" Index="0x100100" DataType="0x0005" ObjectType="0x07" Name="Error Register"/>
</register_map>
</root>
My code so far looks like this
namespace Test_XML
{
class Program
{
struct RegisterEntry
{
public UInt32 index;
public UInt16 dataType;
public UInt16 objectType;
public string name;
};
static void Main(string[] args)
{
XDocument doc = XDocument.Load("registers.xml");
var registers = doc.Descendants("register_map");
foreach (var register in registers)
{
// Fill up a list of RegisterEntrys with contents of XML
}
Console.ReadLine();
}
}
}
How can I extract the parameters from "registers" and place them in a RegisterEntry object?
You can use
var registers = doc.XPathSelectElements("/root/register_map/Register");
It will give you collection of Registernodes, so you wil be able to access their attributes and populate your RegisterEntry object something like:
foreach (var register in registers)
{
var dataType = register.Attribute("DataType").Value;
//the rest of the code
}
Notice XPathSelectElements is an extension method in System.Xml.XPath namespace. Make sure you've referenced System.Xml.Linq assembly in order to use it.
You should use .Attributes["name"].Value. I take it you want those values converted to Int as well, so we need an additional Convert.ToInt(string, base);
var RegisteryEntryList = new List<RegistryEntry>();
foreach (var register in registers)
{
//create a new RegistryEntry
var obj = new RegistryEntry();
//convert your string to an int value and save it
obj.index = Convert.ToInt32(register.Attributes["Index"].Value.Split('x')[1], 8);
obj.datatype = Convert.ToInt32(register.Attributes["DataType"].Value.Split('x')[1], 8);
//... your remaining properties
RegisteryEntryList.Add(obj);
}
Please note: If your Index is binary (base 2) you need to adapt the conversion accordingly. For more information see https://msdn.microsoft.com/en-us/library/1k20k614(v=vs.110).aspx
Your query will get you all elements with the name register_map - you want all Register elements. Change it to this:
var registers = doc.Descendants("Registers");
Then iterate through them and take the values you need, converting them to the required types.
foreach (var register in registers)
{
var indexHex = (string)register.Attribute("Index");
var index = Convert.ToUInt32(indexHex, 16);
var dataTypeHex = (string)register.Attribute("DataType");
var dataType = Convert.ToUInt16(dataTypeHex, 16);
var objectTypeHex = (string)register.Attribute("ObjectType");
var objectType = Convert.ToUInt16(objectTypeHex, 16);
var name = (string)register.Attribute("Name");
var entry = new RegisterEntry
{
index = index,
dataType = dataType,
objectType = objectType,
name = name,
};
// do something with entry
}
Use xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<root>" +
"<register_map>" +
"<Register ID=\"1\" Index=\"0x100000\" DataType=\"0x0007\" ObjectType=\"0x07\" Name=\"Device Type\"/>" +
"<Register ID=\"2\" Index=\"0x100100\" DataType=\"0x0005\" ObjectType=\"0x07\" Name=\"Error Register\"/>" +
"</register_map>" +
"</root>";
XDocument doc = XDocument.Parse(xml);
var results = doc.Descendants("Register").Select(x => new {
id = (int)x.Attribute("ID"),
index = int.Parse(x.Attribute("Index").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
dataType = int.Parse(x.Attribute("DataType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
objectType = int.Parse(x.Attribute("ObjectType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
name = (string)x.Attribute("Name")
}).ToList();
}
}
}