="1.0"="utf-8"
<Controllers>
<PLC ConfigName="OP010">
<IPAddress>172.21.1.1</IPAddress>
<SubnetMask>255.255.255.0</SubnetMask>
<ENxT_Slot>1</ENxT_Slot>
<CPU_Slot>0</CPU_Slot>
<ProgName>OP010_ePRESS</ProgName>
<CurveTag>Curve</CurveTag>
<CommTimeOut>1000</CommTimeOut>
<UpdateRate>250</UpdateRate>
</PLC>
<PLC ConfigName="OP020">
<IPAddress>172.21.1.2</IPAddress>
<SubnetMask>255.255.254.0</SubnetMask>
<ENxT_Slot>1</ENxT_Slot>
<CPU_Slot>0</CPU_Slot>
<ProgName>OP020_ePRESS</ProgName>
<CurveTag>Curve</CurveTag>
<CommTimeOut>1000</CommTimeOut>
<UpdateRate>250</UpdateRate>
</PLC>
</Controllers>
I'm taking a swag at LINQ with XML with VS2010 and C#. Using the XML shown above, I've got the following code to pull the XElements out of the XML this way -
var xmlElemList = from xmlElements in XElement.Load(@"configuration.xml").Elements("PLC") select xmlElements;
foreach (var xmlElem in xmlElemList)
{
I can iterate through each element with a foreach, I can print the contents to the console. I can pull out the attribute from the <plc configname="OPxxx">. What I can't figure out how to do is either 1) Map the data into a class object I have with properties of the same name, or at the very least 2) assign the descendants of each <plc configname...=""> to variables without using a very painful process such as what I post below. There has got to be an easier way.
What does work (UGLY!!!) is the following -
Create a set of delimiters for each set of data -
String[] ip_addr_delim = new String[2] { "</IPAddress>", "<IPAddress>" };
String[] sub_net_delim = new String[2] { "<SubnetMask>", "</SubnetMask>" };
String[] comm_slot_delim = new String[2] { "<ENxT_Slot>", "</ENxT_Slot" };
String[] cpu_slot_delim = new String[2] { "<CPU_Slot>", "</CPU_Slot>" };
String[] prog_name_delim = new String[2] { "<ProgName>", "</ProgName>" };
String[] curve_tag_delim = new String[2] { "<CurveTag>", "</CurveTag>" };
String[] timeout_delim = new String[2] { "<CommTimeOut>", "</CommTimeOut>" };
String[] update_rate_delim = new String[2] { "<UpdateRate>", "</UpdateRate>" };
Then iterate through them all, creating a PLC class object, assigning values, then adding..rinse and repeat. I can't believe there isn't a much more elegant solution.
foreach (var xmlElem in xmlElemList)
{
string[] temp;
ActiveCfg.ConfigName = xmlElem.FirstAttribute.Value.ToString();
temp = xmlElem.ToString().Split(ip_addr_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.IPAddress = temp[1];
temp = xmlElem.ToString().Split(sub_net_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.SubnetMask = temp[1];
temp = xmlElem.ToString().Split(comm_slot_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.ENxT_Slot = Convert.ToByte(temp[1]);
temp = xmlElem.ToString().Split(cpu_slot_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.CPU_Slot = Convert.ToByte(temp[1]);
temp = xmlElem.ToString().Split(prog_name_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.ProgName = temp[1];
temp = xmlElem.ToString().Split(curve_tag_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.CurveTag = temp[1];
temp = xmlElem.ToString().Split(timeout_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.CommTimeOut = Convert.ToInt32(temp[1]);
temp = xmlElem.ToString().Split(update_rate_delim, StringSplitOptions.RemoveEmptyEntries);
ActiveCfg.UpdateRate = Convert.ToInt32(temp[1]);
PLC_List.Add(this.ActiveCfg);
}
I should add that I am free to change the XML format in the .XML to fit my needs so if that makes something easier without breaking rules of XML, I'm open to it.