Example #1
0
        //Reading navigation map starting from <navMap> node
        private static async Task <EpubNavigationMap> ReadNavigationMapAsync(XmlReader reader)
        {
            EpubNavigationMap result = new EpubNavigationMap();
            bool mapFound            = await reader.ReadToFollowingAsync("navMap", "http://www.daisy.org/z3986/2005/ncx/");

            if (!mapFound)
            {
                throw new Exception("EPUB parsing error: navMap section not found in the .toc file.");
            }
            //reading till the </navMap> tag appearance
            while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "navMap"))
            {
                //We are looking for a top-level <navPoint> entries, considering that it could be any level of nesting:
                if ((reader.LocalName == "navPoint") && (reader.NodeType != XmlNodeType.EndElement))
                {
                    //We need to create a subreader space to limit the scope for each single navPoint
                    XmlReader           subReader       = reader.ReadSubtree();
                    EpubNavigationPoint navigationPoint = await ReadNavigationPointAsync(subReader);

                    //we reached the end of the top-level <navPoint> entry and it is time to add it to collection and to get rid of the sub-reader
                    result.Add(navigationPoint);
                    subReader.Dispose();
                }
            }
            return(result);
        }
Example #2
0
        private static EpubNavigationMap ReadNavigationMap(XElement navigationMapNode)
        {
            EpubNavigationMap result = new EpubNavigationMap();

            foreach (XElement navigationPointNode in navigationMapNode.Elements())
            {
                if (String.Compare(navigationPointNode.Name.LocalName, "navPoint", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    EpubNavigationPoint navigationPoint = ReadNavigationPoint(navigationPointNode);
                    result.Add(navigationPoint);
                }
            }
            return(result);
        }
Example #3
0
        public static async Task <EpubNavigation> ReadNavigationAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            EpubNavigation result = new EpubNavigation();
            string         tocId  = package.Spine.Toc;

            if (String.IsNullOrEmpty(tocId))
            {
                throw new Exception("EPUB parsing error: TOC ID is empty.");
            }
            EpubManifestItem tocManifestItem = package.Manifest.FirstOrDefault(item => String.Compare(item.Id, tocId, StringComparison.OrdinalIgnoreCase) == 0);

            if (tocManifestItem == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} is larger than 2 Gb.", tocFileEntryPath));
            }
            XDocument containerDocument;

            using (Stream containerStream = tocFileEntry.Open())
            {
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }
            XNamespace ncxNamespace = "http://www.daisy.org/z3986/2005/ncx/";
            XElement   ncxNode      = containerDocument.Element(ncxNamespace + "ncx");

            if (ncxNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain ncx element.");
            }
            XElement headNode = ncxNode.Element(ncxNamespace + "head");

            if (headNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain head element.");
            }
            EpubNavigationHead navigationHead = ReadNavigationHead(headNode);

            result.Head = navigationHead;
            XElement docTitleNode = ncxNode.Element(ncxNamespace + "docTitle");

            if (docTitleNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain docTitle element.");
            }
            EpubNavigationDocTitle navigationDocTitle = ReadNavigationDocTitle(docTitleNode);

            result.DocTitle   = navigationDocTitle;
            result.DocAuthors = new List <EpubNavigationDocAuthor>();
            foreach (XElement docAuthorNode in ncxNode.Elements(ncxNamespace + "docAuthor"))
            {
                EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
                result.DocAuthors.Add(navigationDocAuthor);
            }
            XElement navMapNode = ncxNode.Element(ncxNamespace + "navMap");

            if (navMapNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain navMap element.");
            }
            EpubNavigationMap navMap = ReadNavigationMap(navMapNode);

            result.NavMap = navMap;
            XElement pageListNode = ncxNode.Element(ncxNamespace + "pageList");

            if (pageListNode != null)
            {
                EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode);
                result.PageList = pageList;
            }
            result.NavLists = new List <EpubNavigationList>();
            foreach (XElement navigationListNode in ncxNode.Elements(ncxNamespace + "navList"))
            {
                EpubNavigationList navigationList = ReadNavigationList(navigationListNode);
                result.NavLists.Add(navigationList);
            }
            return(result);
        }
        public static EpubNavigation ReadNavigation(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            EpubNavigation result = new EpubNavigation();
            string         tocId  = package.Spine.Toc;

            if (String.IsNullOrEmpty(tocId))
            {
                throw new Exception("EPUB parsing error: TOC ID is empty.");
            }
            EpubManifestItem tocManifestItem = package.Manifest.FirstOrDefault(item => String.Compare(item.Id, tocId, StringComparison.OrdinalIgnoreCase) == 0);

            if (tocManifestItem == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC item {0} not found in EPUB manifest.", tocId));
            }
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} not found in archive.", tocFileEntryPath));
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception(String.Format("EPUB parsing error: TOC file {0} is bigger than 2 Gb.", tocFileEntryPath));
            }
            XmlDocument containerDocument;

            using (Stream containerStream = tocFileEntry.Open())
                containerDocument = XmlUtils.LoadDocument(containerStream);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(containerDocument.NameTable);

            xmlNamespaceManager.AddNamespace("ncx", "http://www.daisy.org/z3986/2005/ncx/");
            XmlNode headNode = containerDocument.DocumentElement.SelectSingleNode("ncx:head", xmlNamespaceManager);

            if (headNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain head element");
            }
            EpubNavigationHead navigationHead = ReadNavigationHead(headNode);

            result.Head = navigationHead;
            XmlNode docTitleNode = containerDocument.DocumentElement.SelectSingleNode("ncx:docTitle", xmlNamespaceManager);

            if (docTitleNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain docTitle element");
            }
            EpubNavigationDocTitle navigationDocTitle = ReadNavigationDocTitle(docTitleNode);

            result.DocTitle   = navigationDocTitle;
            result.DocAuthors = new List <EpubNavigationDocAuthor>();
            foreach (XmlNode docAuthorNode in containerDocument.DocumentElement.SelectNodes("ncx:docAuthor", xmlNamespaceManager))
            {
                EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
                result.DocAuthors.Add(navigationDocAuthor);
            }
            XmlNode navMapNode = containerDocument.DocumentElement.SelectSingleNode("ncx:navMap", xmlNamespaceManager);

            if (navMapNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain navMap element");
            }
            EpubNavigationMap navMap = ReadNavigationMap(navMapNode);

            result.NavMap = navMap;
            XmlNode pageListNode = containerDocument.DocumentElement.SelectSingleNode("ncx:pageList", xmlNamespaceManager);

            if (pageListNode != null)
            {
                EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode);
                result.PageList = pageList;
            }
            result.NavLists = new List <EpubNavigationList>();
            foreach (XmlNode navigationListNode in containerDocument.DocumentElement.SelectNodes("ncx:navList", xmlNamespaceManager))
            {
                EpubNavigationList navigationList = ReadNavigationList(navigationListNode);
                result.NavLists.Add(navigationList);
            }
            return(result);
        }
        //Reading navigation map starting from <navMap> node
        private static async Task<EpubNavigationMap> ReadNavigationMapAsync(XmlReader reader)
        {
            EpubNavigationMap result = new EpubNavigationMap();
            bool mapFound = await reader.ReadToFollowingAsync("navMap", "http://www.daisy.org/z3986/2005/ncx/");
            if (!mapFound)
                throw new Exception("EPUB parsing error: navMap section not found in the .toc file.");
            //reading till the </navMap> tag appearance
            while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "navMap"))
            {
                //We are looking for a top-level <navPoint> entries, considering that it could be any level of nesting:
                if ((reader.LocalName == "navPoint") && (reader.NodeType != XmlNodeType.EndElement))
                {
                    //We need to create a subreader space to limit the scope for each single navPoint
                    XmlReader subReader = reader.ReadSubtree();
                    EpubNavigationPoint navigationPoint = await ReadNavigationPointAsync(subReader);
                    //we reached the end of the top-level <navPoint> entry and it is time to add it to collection and to get rid of the sub-reader
                    result.Add(navigationPoint);
                    subReader.Dispose();

                }
            }
            return result;
        }
Example #6
0
 private static EpubNavigationMap ReadNavigationMap(XmlNode navigationMapNode)
 {
     EpubNavigationMap result = new EpubNavigationMap();
     foreach (XmlNode navigationPointNode in navigationMapNode.ChildNodes)
         if (String.Compare(navigationPointNode.LocalName, "navPoint", StringComparison.OrdinalIgnoreCase) == 0)
         {
             EpubNavigationPoint navigationPoint = ReadNavigationPoint(navigationPointNode);
             result.Add(navigationPoint);
         }
     return result;
 }