// --------------------------------------------------------------------------------------------------------------------
//
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
//
//
// Imports chapter markers in the ChaptersDb.org XML format
// More info: http://www.chapterdb.org/docs
//
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrakeWPF.Utilities.Input
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using HandBrakeWPF.Helpers;
///
/// Imports chapter markers in the ChaptersDb.org XML format
/// More info: http://www.chapterdb.org/docs
///
internal class ChapterImporterXml
{
///
/// The file filter value for the OpenFileDialog
///
public static string FileFilter => "XML files (*.xml)|*.xml";
///
/// Imports all chapter information from the given into the dictionary.
///
/// The full path and filename of the chapter marker file to import
/// The dictionary that should be populated with parsed chapter markers
public static void Import(string filename, ref Dictionary> chapterMap)
{
XDocument xDoc = XDocument.Load(new StreamReader(filename));
var xRoot = xDoc.Root;
if (xRoot == null)
return;
// Indexing is 1-based
int chapterMapIdx = 1;
// Get all chapters in the document
var chapters = xRoot.XPathSelectElements("/Chapters/EditionEntry/ChapterAtom");
TimeSpan prevChapterStart = TimeSpan.Zero;
foreach (XElement chapter in chapters)
{
// Extract and clean up any special XML escape characters
var chapterName = chapter.XPathSelectElement("ChapterDisplay/ChapterString")?.Value;
if (!string.IsNullOrWhiteSpace(chapterName))
{
chapterName = XmlConvert.DecodeName(chapterName);
}
var chapterStartRaw = chapter.XPathSelectElement("ChapterTimeStart")?.Value;
if (!string.IsNullOrWhiteSpace(chapterStartRaw))
{
// Format: 02:35:05 and 02:35:05.2957333
var chapterStart = TimeSpanHelper.ParseChapterTimeStart(chapterStartRaw);
// If we're past the first chapter in the file then calculate the duration for the previous chapter
if (chapterMapIdx > 1)
{
var old = chapterMap[chapterMapIdx - 1];
chapterMap[chapterMapIdx - 1] = new Tuple(
old.Item1,
chapterStart - prevChapterStart);
}
prevChapterStart = chapterStart;
}
// Save the chapter info, we calculate the duration in the next iteration (look back)
chapterMap[chapterMapIdx++] = new Tuple(chapterName, TimeSpan.Zero);
}
}
}
}