Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

C#: Reading and appending XML file

Hi

Using the XML file bellow as a log I'm gathering information about TV shows using TMDB api (Not part of question just background)

How do I access each show name and its childs episodes details?

Ultimately I want to be able to access a  Episode path and if doesn't exist in the xml create a new entry or parent show

XmlReader
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace XmlReader
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(@"J:\Media\TV\TV.xml");
            XmlNodeList Nodes = xmlDoc.SelectNodes("TV/Show");
            for(int I =0; I <= Nodes.Count; I++)
            {
                Console.WriteLine(Nodes[I].Name); // This throws an error 
            }

            Console.ReadKey();
        }
    }
}

Open in new window


TV.xml

<?xml version="1.0"?>
<TV>
  <Show>
      <Name>MacGyver 2016</Name>
      <FolderName>MacGyver 2016</FolderName>
      <TMDBid>67133</TMDBid>
      <Season>3</Season>
      <Episode>
          <EpisodeNumber>1</EpisodeNumber>
          <EpisodeName>Improvise</EpisodeName>
          <BackDrop>https://image.tmdb.org/t/p/w350_and_h196_bestv2/eQMVJkBltvID73sh9vvTistssS6.jpg</BackDrop>
      <FullPath>J:\Media\TV\MacGyver (2016)\S03\Macgyver.2016.S03E01.Improvise.mp4</FullPath>
      </Episode>
  </Show>
</TV>

Open in new window



I'm assuming I would create a new episode by appending to it's parent show (something like bellow) but how do I find the correct show / season
Similarly How do create  a new show?

XmlNode EP = xmlDoc.CreateElement("Episode");
            XmlNode EpNum = xmlDoc.CreateElement("EpisodeNumber");
            EpNum.Value = "2";
            EpNum.AppendChild(EP);
            // repeate for each element

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi trevor1940;

This is how you can add a new episode to the document.
// Show to add to
var showname = "MacGyver 2016";
// Season to add to
var season = "3";
// Episode to add
var episode = new XElement("Episode",
    new XElement("EpisodeNumber", "2"),
    new XElement("EpisodeName", "Tick Tock"),
    new XElement("BackDrop", "https://image.tmdb.org/t/p/w350_and_h196_bestv2/eQMVJkBltvID73sh9vvTistssS67.jpg"),
    new XElement("FullPath", @"J:\Media\TV\MacGyver (2016)\S03\Macgyver.2016.S03E02.TickTock.mp4")
    );

// Load the XML Document using Linq to XML
var xdoc = XDocument.Load("TV.xml");
// Query the Document for the Show to add episode to
var show = (from node in xdoc.Descendants("Show")
            where node.Element("Name").Value == showname && node.Element("Season").Value == season
            select node.Element("Episode")).FirstOrDefault();

// See if the Show was found and add episode if it was
if (show != null)
{
    // Add the episode
    show.AddAfterSelf(episode);
    // Save the document with the new episode
    xdoc.Save("TVNew.xml");
}

Open in new window

Avatar of trevor1940
trevor1940

ASKER

Hi
Thanx for your reply   A couple of questions if I may

Why is FullPath '.ToList()' and other elements are just '.value'?

FullPath = ep.Element("FullPath").Value }).ToList()

Open in new window


Ultimately when running the program  I'll be traversing the file system so I'll be able identify from the files Show name, Season and episoeds

Is there a quick way to see if a show or episode exists?

something like

var ShowName = "The Walking Dead";
var season = 9;
if(exists(shows.ShowName))
  {
         // Do Stuff
         // Check If Season & Episode exists if not Add it
   }
else
  {
     // Add new show to XML ShowName
   }

Open in new window


Finally
When adding a new Episode If both Episodes 1 & 3 exists  will  Episode 2 be added last?
To your question, "Why is FullPath '.ToList()' and other elements are just '.value'?", The fullPath node is not the only node going to the ToList method but all the children of the Episode node are also in the list see below.
<Episode>
    <EpisodeNumber>1</EpisodeNumber>
    <EpisodeName>Improvise</EpisodeName>
    <BackDrop>https://image.tmdb.org/t/p/w350_and_h196_bestv2/eQMVJkBltvID73sh9vvTistssS6.jpg</BackDrop>
    <FullPath>J:\Media\TV\MacGyver (2016)\S03\Macgyver.2016.S03E01.Improvise.mp4</FullPath>
</Episode>

Open in new window

To your question, "Is there a quick way to see if a show or episode exists?", This is a way to do that.
// Load the XML Document using Linq to XML
// Define this at class level
XDocument tvDoc = XDocument.Load("TV.xml");

// Checks for the existence of a Show Season and Episode
private bool CheckShow(string showname, string season, string episode)
{
    var results = (from node in tvDoc.Descendants("Show")
                   where node.Element("Name").Value == showname &&
                         node.Element("Season").Value == season &&
                         node.Element("Episode").Element("EpisodeNumber").Value == episode
                   select node).FirstOrDefault();
    return results != null ? true : false;
}

private void button3_Click(object sender, EventArgs e)
{
    var showName = "The Walking Dead";
    var season = "3";
    var episode = "1";


    if (CheckShow(showName, season, episode))
    {
        Console.WriteLine("Exists");
    } else
    {
        Console.WriteLine("Does Not Exists");
    }
}

Open in new window

To your question, "When adding a new Episode If both Episodes 1 & 3 exists  will  Episode 2 be added last?" , in the code I posted yes but after inserting you can reorder the elements. See How to: Sort Elements on Multiple Keys (C#) .
Thank You very much
I think I have a lot to learn

I managed to break it so posted a follow up question