Редактирование элемента XML, который содержит несколько значений - PullRequest
0 голосов
/ 08 января 2020

Так что я пытаюсь что-то выяснить, много читал о stackoverflow. У меня есть фид данных с более чем 6 тысячами товаров для моего интернет-магазина.

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

Поэтому я хочу отредактировать все идентификаторы <category>, поэтому в этом примере 2403,2449,2462 к соответствующему тексту.

Пример:

enter image description here

Каков наилучший способ сделать это?

Код, который я получил до сих пор :

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"))
        {

        }
    }

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Итак, у вас есть проблема, которая существует из нескольких проблем. Вы должны научиться разбивать большие проблемы на более мелкие. Вы могли бы начать с использования более дружественного XML API, потому что этот довольно запутанный. В любом случае, используя ваш код в качестве отправной точки:

// 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;               
        }
    }

Этот код не проверяет ошибки. Поэтому, если значение содержит нецелые числа, оно выдаст исключение. Если словарь не содержит записи для данного числа, он выдаст исключение. Как их решить, оставлено для вас в качестве упражнения.

Вероятно, есть проблема с разделом CDATA, см. Как редактировать текстовое содержимое, сохраняя его в блоке CDATA? .

0 голосов
/ 08 января 2020

Попробуйте следующее:

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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...