-1

So I am trying to figure something out, been reading a lot on stackoverflow. I have a data feed with over 6 thousand products, it's for my webshop.

<product>
    <id>0000</id>
    <category><![CDATA[2403,2449,2462]]></category>
    <name><![CDATA[XXL Bierlaars]]></name>
    <attribute1/>
    <attribute2/>
    <value1/>
    <value2/>
    <description>Test</description>
    <brand>3209</brand>
    <feature/>
    <price>30</price>
    <pvp>11.99</pvp>
    <pvd>5.99</pvd>
    <iva>21</iva>
    <video>0</video>
    <ean13>0000</ean13>
    <width>16</width>
    <height>23.5</height>
    <depth>10.5</depth>
    <weight>0.63</weight>
    <stock>6</stock>
    <date_add>2012-05-10 17:34:12</date_add>
    <date_upd>2019-12-30 15:09:25</date_upd>
    <image1>https://www.google.com</image1>
    <image2>https://www.google.com</image2>
    <image3/>
    <image4/>
    <image5/>
    <image6/>
    <image7/>
    <image8/>
</product>

So I want to edit all the <category> ids so in this example 2403,2449,2462 to the corresponding text.

Example:

enter image description here

What would be the best way to do this?

Code I got so far:

XDocument doc = XDocument.Load("test.xml");

foreach(XNode node in doc.DescendantNodes())
{
    if(node is XElement)
    {
        XElement element = (XElement)node;
        if (element.Name.LocalName.Equals("category"))
        {

        }
    }
GSerg
  • 76,472
  • 17
  • 159
  • 346
Youri B.
  • 1
  • 1
  • Missing the code you have written so far... – Max Jan 08 '20 at 11:36
  • Added the code I got so far, sorry forgot about it. – Youri B. Jan 08 '20 at 11:40
  • You split the values, look up the values-to-replace, and rebuild a string with the replaced values. What have you tried? It's got to do with `Value.Split(',')`, some lookup, and a `string.Join(',', lookedUpValues)`. – CodeCaster Jan 08 '20 at 11:41
  • What would be the best way to store all the id's with the corresponding text? And what I came up with so far is: `string[] testArray = element.ToString().Split(','); foreach(string s in testArray) { }` – Youri B. Jan 08 '20 at 11:57
  • @CoadeCoasster : When my code is using a dictionary like you suggested? – jdweng Jan 08 '20 at 13:55

2 Answers2

0

So you have a problem that exists of multiple problems. You need to learn to break up larger problems into smaller ones. You could start by using a more friendly XML API as well, because this one is quite convoluted. Anyway, using your code as starting point:

// create a dictionary to hold the categories:

var categories = new Dictionary<int, string>
{
    { 2403, "Foo" },
    { 2404, "Bar" }
};

foreach(XNode node in doc.DescendantNodes())
{
    if(node is XElement)
    {
        XElement element = (XElement)node;
        if (element.Name.LocalName.Equals("category"))
        {

            var ids = element.Value;

            // Split the comma-separated integers, parse them and store them in a list
            var idList = ids.Split(',').Select(int.Parse).ToList();

            // Translate the IDs to the appropriate strings
            var categoryNames = idList.Select(i => categories[i]).ToList();

            // Concatenate the category names into a single string again
            var concatenated = string.Join(",", categories);

            // And assign it to the value again
            element.Value = concatenated;               
        }
    }

This code does no error checking. So if the value contains non-integers, it'll throw an exception. If the dictionary doesn't contain an entry for a given number, it'll throw an exception. How to solve those is left as an exercise for you.

There's probably also an issue with it being a CDATA section, see How to do edit text content keeping it in a CDATA block?.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
-1

Try following :

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

namespace ConsoleApplication146
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME);
             Dictionary<string, List<object>> dict = doc.Descendants("product")
                .Select(x => new { id = (string)x.Element("id"), category = GetCDATA(x.Element("category").FirstNode), name = (string)GetCDATA(x.Element("name").FirstNode) })
                .SelectMany(x => x.category.Split(new char[] {','}).Select(y => new { id =int.Parse(y), category = y, name = x.name}))
                .GroupBy(x => x.category, y => (object)y)
                .ToDictionary(x => x.Key, y => y.ToList());
        }
        static string GetCDATA(object input)
        {
            string pattern = @"CDATA\[(?'data'[^\]]+)";
            return Regex.Match(input.ToString(), pattern).Groups["data"].Value;
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20