XML powtarzalne sekcje

0

Dzień dobry.

Panowie, męczę się okrutnie z serializacją do XMLa, a właściwie z takim przypadkiem jednym. Dostałem specyfikację od człowieka któremu chcę dostarczać informację o produktach i podał mi taką strukturę pliku xml (w uproszczeniu):

<?xml version="1.0" encoding="UTF-8"?>
<productsFeed>
    <schemaVersion>1.0</schemaVersion>
    <fileLastModificationDateTime>2018-07-26T10:15:30</fileLastModificationDateTime>
    <productsData>
        <product>
            <identification>
                <EANlist>
                    <EAN>0001</EAN>
                    <EAN>0002</EAN>
                </EANlist>
                <productId>id produktu</productId>
                <manufacturerProductId>id produktu producemta</manufacturerProductId>
            </identification>
            <description>
                <productName>nazwa produktu</productName>
                <productDescription>opis produktu</productDescription>
                <parametersList>
                    <parameter>
                        <parameterName>nazwa parametru</parameterName>
                        <parameterValue>wartosc</parameterValue>
                        <parameterUnit>jednostka</parameterUnit>
                    </parameter>
                </parametersList>
            </description>
        </product>
        <product>
            <identification>
                <EANlist>
                    <EAN>0003</EAN>
                    <EAN>0004</EAN>
                </EANlist>
                <productId>id produktu</productId>
                <manufacturerProductId>id produktu producemta</manufacturerProductId>
            </identification>
            <description>
                <productName>nazwa produktu</productName>
                <productDescription>opis produktu</productDescription>
                <parametersList>
                    <parameter>
                        <parameterName>nazwa parametru</parameterName>
                        <parameterValue>wartosc</parameterValue>
                        <parameterUnit>jednostka</parameterUnit>
                    </parameter>
                </parametersList>
            </description>
        </product>
    </productsData>
</productsFeed>

I teraz tak, zupełnie nie wiem czy dobrze robię czy źle, ale na początek stworzyłem sobie takie coś (niepełne odwzorowanie, ale na początek wystarcza):

public class productsFeed
    {
        public string schemaVersion;
        public string fileLastModificationDateTime;
        public ProdData productsData;
    }

    public class ProdData
    {
        public Product product;
    }

    public class Product
    {
        public Identifiaction identification;
        public Description description;
    }

    public class Identifiaction
    {
        public string productId;
        public string manufacturerProductId;
    }

    public class Description
    {
        public string productName;
        public string productDescription;
    }

I później wypełniam tą strukturę danymi

        public void CreatePO(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(productsFeed));
            TextWriter writer = new StreamWriter(filename);
            productsFeed po = new productsFeed();

            po.schemaVersion = "1.0";
            po.fileLastModificationDateTime = DateTime.Now.ToString();

            ProdData pd = new ProdData();
            Product pr = new Product();
            Identifiaction ident = new Identifiaction();
            Description desc = new Description();

            po.productsData = pd;
            pd.product = pr;
            pr.identification = ident;
            pr.description = desc;

            ident.productId = "123";
            ident.manufacturerProductId = "4567";
            desc.productDescription = "Opis produktu";
            desc.productName = "Nazwa produktu";

            serializer.Serialize(writer, po);
            writer.Close();
        }

Wszystko jest spoko, tworzy mi plik, wygląda ok, tylko utknąłem w momencie takim że sekcja <product> jest powtarzalna... Dżizas no, nie wiem jak się za to zabrać, tworzyć jakąś listę? Jak?

Generalnie z taką płaską strukturą nie mam problemów bo pobieram sobie cały set danych z bazy, lecę po wierszach i odpowiednim konstruktorem podaję dane do listy którą następnie serializuję, ale jak się zagnieżdżają sekcje to nie wiem jak się do tego dobierać w ogóle i czy to co stworzyłem ma jakiś sens?

1

W visual studio masz coś takiego Jak Paste special XML a dokładnie Edit -> Paste Special -> XML kopiujesz tam swojego xml i Ci tworzy klasy nie musisz się męczyć ręcznie tego pisać.

0

A to wiem że jak wkleję to mi klasa wylatuje gotowa, ale dalej nie wiem jak ją wypełniać danymi, myślałem że jak ręcznie nadziubię to mi się rozjaśni coś ale nic nie dzwoni w żadnym kościele...

Chodzi o to że tych sekcji <product> chciałbym mieć 100, 200... w jaki sposób je wypełniać i się do nich odwoływać?

1
    public class ProdData
    {
        public List<Product> product;
    }
0

Dobra, wracam do tematu po dwóch tygodniach przerwy :D
Wydawało mi się że produkuję to co chcę, ale znów pojawił mi się problem z elementami <parametersList> -> <parameter>.
Chcący uzyskać dokładnie taką samą strukturę XMLa zbudowałem sobie klasę Parameter która to wygląda tak:

    public class Parameter
    {
        public string parameterName;
        public string parameterValue;
        public string parameterUnit;

        public Parameter() { }

        public Parameter (string _pName, string _pValue, string _pUnit)
        {
            this.parameterName = _pName;
            this.parameterUnit = _pUnit;
            this.parameterValue = _pValue;
        }
    }

Następnie tą klasę ładuje w klasę Description:

    public class Description
    {
        //[System.Xml.Serialization.XmlArrayAttribute()]
        //[System.Xml.Serialization.XmlArrayItemAttribute("EAN", IsNullable = false)]
        public string productName;
        public string productDescription;
        public List<Parameter> parametersList;
    }

A w ogóle całość wygląda tak:

    [XmlRoot("productsFeed", IsNullable = true)]

    public class productsFeed
    {
        [XmlElement(IsNullable = true)]
        public string schemaVersion;
        public string fileLastModificationDateTime;
        public List<Product> productsData;
    }

    public class Product
    {
        [XmlElement(IsNullable = false)]

        public Identifiaction identification;
        public Description description;

        public Product() { }

        public Product(string _idproduktu, string _exProductId, string _productdesc, string _productname, List<string> _numerEan, List<Parameter> _parameter)
        {
            Identifiaction ident = new Identifiaction();
            ident.productId = _idproduktu;
            ident.exProductId = _exProductId;
            ident.EANlist = _numerEan;

            Description desc = new Description();
            desc.productDescription = _productdesc;
            desc.productName = _productname;
            desc.parametersList = _parameter;

            this.identification = ident;
            this.description = desc;
        }

        public Product(string _idproduktu, string _exProductId, string _productdesc, string _productname, string _numerEan1, List<Parameter> _parameter)
        {
            List<string> numeryEan = new List<string>();
            Identifiaction ident = new Identifiaction();
            ident.productId = _idproduktu;
            ident.exProductId = _exProductId;
            numeryEan.Add(_numerEan1);
            ident.EANlist = numeryEan;

            Description desc = new Description();
            desc.productDescription = _productdesc;
            desc.productName = _productname;
            desc.parametersList = _parameter;

            this.identification = ident;
            this.description = desc;
        }

    }

    public class Identifiaction
    {
        [System.Xml.Serialization.XmlArrayAttribute()]
        [System.Xml.Serialization.XmlArrayItemAttribute("EAN", IsNullable = false)]
        public List<string> EANlist;
        public string productId;
        public string exProductId;
    }

    public class Description
    {
        //[System.Xml.Serialization.XmlArrayAttribute()]
        //[System.Xml.Serialization.XmlArrayItemAttribute("EAN", IsNullable = false)]
        public string productName;
        public string productDescription;
        public List<Parameter> parametersList;
    }

    public class Parameter
    {
        public string parameterName;
        public string parameterValue;
        public string parameterUnit;

        public Parameter() { }

        public Parameter (string _pName, string _pValue, string _pUnit)
        {
            this.parameterName = _pName;
            this.parameterUnit = _pUnit;
            this.parameterValue = _pValue;
        }
    }

i później wypełniam to jakimiś śmieciami póki co:

        public void CreatePO(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(productsFeed));
            TextWriter writer = new StreamWriter(filename);
            productsFeed po = new productsFeed();
            List<Product> pr = new List<Product>();
            List<string> numeryEan = new List<string>();
            List<Parameter> parameters = new List<Parameter>();

            po.schemaVersion = "1.0";
            po.fileLastModificationDateTime = DateTime.Now.ToString();
            po.productsData = pr;

            for (int i = 0; i < 5; i++)
            {
                parameters.Add(new Parameter("name", "val", "unit"));
                pr.Add(new Product(i.ToString(), i.ToString(), "productdesc", "productname", "1111" + i.ToString(), parameters));
            }

            serializer.Serialize(writer, po);
            writer.Close();
            
        }

I mam problem z Eanami i parameters. Chciałbym za każdym przejściem pętli "zerować" klasę parameters, i przekazywać jedynie to co wrzucę tam przy jednej iteracji. O ile eanów będzie max 2, to mogę je przekazywać do produktu jako osobne zmienne, ale w przypadku parametrów raz będę miał jeden zestaw parametrów dla produktu, innym razem może ich być 5. Tymczasem to co wyprodukowałem, zbiera wszystkie parametry do kupy i wrzuca całość do każdego produktu. Jak to rozsądnie ugryźć?

1 użytkowników online, w tym zalogowanych: 0, gości: 1