C#: how to read attributes of xml elements and subelements

Viewed 92

i have an xml file with the structure in the appendix. I'm trying to write a function in C#, which should do the following: arrange all elements and sub-elements in different lists so that for each component (comp) and each box (cast) the geometric parameters (GeoVar) and the prop parameters (prop) are read out and that they are subordinate to the cast or comp or product. This must be done via the PNr. how can I assign the PNr from the parent element to the GeoVar element or prop element? I don't know how to do that! Thank you for your help...

desired result:

image

<?xml version="1.0" encoding="UTF-8"?>
<Product name="vision" PNr="170000">
    <GeoVar>
        <b>3950.0</b>
        <h>3000.0</h>
        <t>2500.0</t>
        <x>3950.0</x>
        <y>1750.5</y>
        <z>250.0</z>
    </GeoVar>
    <Prop>
        <typ>t1</typ>
        <temp>45</temp>
        <vol>22</vol>
        <class>2</class>
        <year>2010</year>
    </Prop>
    <Cast name="C1" PNr="170001">
        <GeoVar>
            <b>3950.0</b>
            <h>3000.0</h>
            <t>2500.0</t>
        </GeoVar>
        <Prop>
            <typ>t1</typ>
            <temp>50</temp>
            <vol>2</vol>
            <face>f2</face>
            <task>t55</task>
            <class>2</class>
            <year>2010</year>
        </Prop>
        <Comp name="ZU-RevCHAMBER_2" typ="CHAMBER_ILS2" PNr="160502">
            <GeoVar>
                <b>3125.0</b>
                <h>3010.0</h>
                <t>2000.0</t>
            </GeoVar>
            <Prop>
                <typ>t1</typ>
                <face>f2</face>
                <task>t55</task>
                <class>2</class>
                <year>2010</year>
                <srf>20</srf>
            </Prop>
        </Comp>
        <Comp name="ZU-RevCHAMBER_3" typ="CHAMBER_ILS3" PNr="160503">
            <GeoVar>
                <b>3125.0</b>
                <h>3010.0</h>
                <t>2000.0</t>
            </GeoVar>
            <Prop>
                <typ>t1</typ>
                <face>f2</face>
                <task>t55</task>
                <class>2</class>
                <year>2010</year>
                <srf>20</srf>
            </Prop>
        </Comp>
        <Comp name="ZU-RevCHAMBER_4" typ="CHAMBER_ILS4" PNr="160504">
            <GeoVar>
                <b>3115.0</b>
                <h>3010.0</h>
                <t>2010.0</t>
            </GeoVar>
            <Prop>
                <typ>t1</typ>
                <face>f2</face>
                <task>t55</task>
                <class>2</class>
                <year>2010</year>
                <srf>20</srf>
            </Prop>
        </Comp>
    </Cast>
    <Cast name="C5" PNr="175001">
        <GeoVar>
            <b>2999.0</b>
            <h>1560.0</h>
            <t>2110.0</t>
        </GeoVar>
        <Prop>
            <typ>wh</typ>
            <temp>50</temp>
            <vol>021</vol>
            <face>z12</face>
            <task>txx</task>
            <class>2</class>
            <year>2009</year>
        </Prop>
        <Comp name="ZU-RevCHAMBER_12" typ="CHAMBER" PNr="160012">
            <GeoVar>
                <b>3125.0</b>
                <h>3010.0</h>
                <t>2000.0</t>
            </GeoVar>
            <Prop>
                <typ>t1</typ>
                <face>f2</face>
                <task>t55</task>
                <class>2</class>
                <year>2010</year>
                <srf>20</srf>
            </Prop>
        </Comp>
    </Cast>
    <Cast name="C6" PNr="175871">
        <GeoVar>
            <b>2999.0</b>
            <h>1560.0</h>
            <t>2110.0</t>
        </GeoVar>
        <Prop>
            <typ>wh</typ>
            <temp>50</temp>
            <vol>021</vol>
            <face>z12</face>
            <task>txx</task>
            <class>2</class>
            <year>2009</year>
        </Prop>
        <Comp name="ZU-RevCHAMBER_12" typ="Typ55" PNr="110502">
            <GeoVar>
                <b>3125.0</b>
                <h>3010.0</h>
                <t>2000.0</t>
            </GeoVar>
            <Prop>
                <typ>t1</typ>
                <face>f2</face>
                <task>t55</task>
                <class>2</class>
                <year>2010</year>
                <srf>20</srf>
            </Prop>
        </Comp>
    </Cast>
</Product>
1 Answers

Here is a recursive algorithm that creates a dictionary.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication186
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XElement root = doc.Root;
            Product.GetTree(null,root, null);

            Dictionary<string, Product> dict = Product.products
                .GroupBy(x => x.PNr, y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

        }
    }
    public class Product
    {
        public static List<Product> products { get; set; }

        public Product parent { get; set; }
        public string name { get; set; }
        public string PNr { get; set; }
        public string typ { get; set; }
        public Dictionary<string, decimal> geoVar { get; set; }
        public Dictionary<string, string> prop { get; set; }
        public List<Product> casts { get; set; }
        public List<Product> components { get; set; }

        public static void GetTree(Product newProduct , XElement element, Product parent)
        {
            if (products == null) products = new List<Product>();
            if (newProduct == null) newProduct = new Product();
            products.Add(newProduct);
            newProduct.parent = parent;
            newProduct.name = (string)element.Attribute("name");
            newProduct.PNr = (string)element.Attribute("PNr");
            newProduct.typ = (string)element.Attribute("typ");

            newProduct.geoVar = element.Element("GeoVar").Elements()
                .GroupBy(x => x.Name.LocalName, y => y)
                .ToDictionary(x => x.Key, y => (decimal)y.FirstOrDefault());

            newProduct.prop = element.Element("Prop").Elements()
                .GroupBy(x => x.Name.LocalName, y => y)
                .ToDictionary(x => x.Key, y => (string)y.FirstOrDefault());

            foreach (XElement comp in element.Elements("Cast"))
            {
                if (newProduct.casts == null) newProduct.casts = new List<Product>();
                Product cast = new Product();
                newProduct.casts.Add(cast);
                GetTree(cast, comp, newProduct);
            }
            foreach (XElement comp in element.Elements("Comp"))
            {
                if (newProduct.components == null) newProduct.components = new List<Product>();
                Product component = new Product();
                newProduct.components.Add(component);
                GetTree(component, comp, newProduct);
            }
        }
    }

}
Related