0

I have an XML file as the following:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <plc1>
        <ip>192.168.0.170</ip>
        <regread>
            <article>1000</article>
            <prod1>100</prod1>
        </regread>
        <regwrite>
            <registerId>2000</registerId>
            <registerDescription>2100</registerDescription>
            <registerTarget>3100</registerTarget>
        </regwrite>
    </plc1>
    <plc2>
        <ip>192.168.0.171</ip>
        <regread>
            <article>1000</article>
            <prod1>200</prod1>
        </regread>
        <regwrite>
            <registerId>2000</registerId>
            <registerDescription>2100</registerDescription>
            <registerTarget>3200</registerTarget>
        </regwrite>
    </plc2>
    <plc3>
        <ip>192.168.0.172</ip>
        <regread>
            <article>1000</article>
            <prod>300</prod>
        </regread>
        <regwrite>
            <registerId>2000</registerId>
            <registerDescription>2100</registerDescription>
            <registerTarget>3300</registerTarget>
        </regwrite>
    </plc3>
</root>

I have to store those nodes' values into a C# struct like this one:

public struct PLC
{
    public string ipAddress;
    public int article;
    public int prod;
    public int registerId;
    public int registerDescription;
    public int registerTarget;
}

I would like to create an array of this struct so that in PLC[0] there will be plc1 node, in PLC[1] there will be plc2 etc..

How can I achieve this? Thanks in advance for your suggestions.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Alessio Raddi
  • 540
  • 1
  • 6
  • 20
  • 2
    You seem to be asking for someone to write some code for you. Stack Overflow is a question and answer site, not a code-writing service. Please [see here](http://stackoverflow.com/help/how-to-ask) to learn how to write effective questions. – Isma Sep 12 '18 at 11:35
  • 1
    Really strange XML: ``, ``, `` – ChristianMurschall Sep 12 '18 at 11:37
  • Have you tried something? Did you encounter a problem? Perhaps you should be asking how to make your serializer (XmlSerializer, DataContractSerializer, XDocument, something else???) work with fields instead of properties? That kind of configuration is *specific to the serializer*. – Panagiotis Kanavos Sep 12 '18 at 11:44
  • https://stackoverflow.com/questions/3356976/how-to-serialize-deserialize-simple-classes-to-xml-and-back – Tiber Septim Sep 12 '18 at 11:47
  • @PanagiotisKanavos, Thanks for replying, I have tried Linq to Xml and XmlDocument, but I couldn't make them work as intended. – Alessio Raddi Sep 12 '18 at 13:08
  • @AlessioRaddi all of them work. Post what you tried. BTW your *struct* doesn't match your XML file. You'd need to *flatten* the XML records to get what you want. That's not deserialization, that happens *after* deserialization – Panagiotis Kanavos Sep 12 '18 at 13:21
  • @AlessioRaddi jdweng's answer deserializes the file with `XDoument.Load` into an XDocument object with all fields. It uses a LINQ query after that to map elements and attributes to another object – Panagiotis Kanavos Sep 12 '18 at 13:24
  • @PanagiotisKanavos I was testing his answer, what I did wrong was reading the children nodes, there I failed. Anyway with his answer I finally got my struct working as I wanted. Thank you all – Alessio Raddi Sep 12 '18 at 13:36

1 Answers1

3

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);

            List<PLC> plcs = doc.Root.Elements().Select(x => new PLC() {
                ipAddress = (string)x.Element("ip"),
                article = (int)x.Descendants("article").FirstOrDefault(),
                prod = (int)x.Descendants().Where(y => y.Name.LocalName.StartsWith("prod")).FirstOrDefault(),
                registerId = (int)x.Descendants("registerId").FirstOrDefault(),
                registerDescription = (int)x.Descendants("registerDescription").FirstOrDefault(),
                registerTarget = (int)x.Descendants("registerTarget").FirstOrDefault()
            }).ToList();


        }
    }
    public class PLC
    {
        public string ipAddress { get; set; }
        public int article { get; set; }
        public int prod { get; set; }
        public int registerId { get; set; }
        public int registerDescription { get; set; }
        public int registerTarget { get; set; }
    }


}

Here is the xml I used

<?xml version="1.0" encoding="UTF-8"?>
<root>
<plc1>

  <ip>192.168.0.170</ip>

  <regread>
    <article>1000</article>
    <prod1>100</prod1>
  </regread>

  <regwrite>
    <registerId>2000</registerId>
    <registerDescription>2100</registerDescription>
    <registerTarget>3100</registerTarget>
  </regwrite>

</plc1>

<plc2>

  <ip>192.168.0.171</ip>

  <regread>
    <article>1000</article>
    <prod1>200</prod1>
  </regread>

  <regwrite>
    <registerId>2000</registerId>
    <registerDescription>2100</registerDescription>
    <registerTarget>3200</registerTarget>
  </regwrite>

</plc2>

<plc3>

  <ip>192.168.0.172</ip>

  <regread>
    <article>1000</article>
    <prod>300</prod>
  </regread>

  <regwrite>
    <registerId>2000</registerId>
    <registerDescription>2100</registerDescription>
    <registerTarget>3300</registerTarget>
  </regwrite>

</plc3>
</root>
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I finally found my error, I had the 'query' to get values from nodes wrong. Thank you for your effort, your solution works perfectly. – Alessio Raddi Sep 12 '18 at 13:38