Home > Software engineering >  Tricky XML Manipulation: Create an element out of its own and other sibling's data
Tricky XML Manipulation: Create an element out of its own and other sibling's data

Time:08-15

I have this replicate scenario my XML document below:

<?xml version="1.0" encoding="utf-8"?>
<Home>
   <Kitchen>
      <Pantry>
         <Ingredients>
            <Name>Tomato</Name>
            <ID>1</Price_ID>
            <Name>Tomato</Name>
            <Income>Sales</Income>  // replace the <Income> element with its value <Sales>
            <Cost>Materials</Cost>
            <Price>100</Price>      // the value for new <Sales> element shall be this <Price> value
          </Ingredients>
          //.. and thousands more sets of ingredients
       </Pantry>
    </Kitchen>
</Home>
//.. and thousands more sets of ingredients

And I want to restructure it in the following manner:

<?xml version="1.0" encoding="utf-8"?>
<Home>
   <Kitchen>
      <Pantry>
         <Ingredients>
            <Name>Tomato</Name>
            <ID>1</ID>
            <Name>Tomato</Name>
            <Sales>100</Sales>      // the <Income> was replaced by its value and the value was taken from the <Price> element that was deleted also
            <Cost>Materials</Cost>           
          </Ingredients>
          //.. and thousands more sets of ingredients
       </Pantry>
    </Kitchen>
</Home>

I'm still trying to figure out how I'm going to do this. I will appreciate any help here.

CodePudding user response:

Using Xml Ling :

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

namespace ConsoleApplication37
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            List<XElement> ingredients = doc.Descendants("Ingredients").ToList();

            foreach (XElement ingredient in ingredients)
            {

                XElement xIncome = ingredient.Element("Income");
                XElement xPrice = ingredient.Element("Price");
                xIncome.ReplaceWith(new XElement("Sales", (string)xPrice));
                xPrice.Remove();
            }
           
        }
    }
}

CodePudding user response:

Firstly create a Class for the new Model

public class NewIngredients 
{
   public int Id { get; set; }
   public string Name { get; set; }
   public decimal Sales { get; set; }
   public string Cost{ get; set; }
}

Presuming the Xml Document is in a file called Kitchen.xml

XElement Kitchen = XElement.Load(@"Kitchen.xml");

then use Linq to Xml to create your new model from the old something like this (Note probably need to check for nulls etc)

var newIngredients = Kitchen.Descendants("Ingredients").Select(x => new NewIngredients
{
  Id = int.Parse(x.Element("ID").Value),
  Name = x.Element("Name").Value,
  Sales = decimal.Parse(x.Element("Price").Value)
  Cost = x.Element("Cost").Value
});

Convert back to xml if needed

var serializer = new XmlSerializer(newIngredients.First().GetType());
serializer.Serialize(Console.Out, newIngredients.First()); //Printed to console but could move to file if needed
  • Related