public static async Task <Epub3NavDocument> ReadEpub3NavDocumentAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package) { Epub3NavDocument result = new Epub3NavDocument(); EpubManifestItem navManifestItem = package.Manifest.FirstOrDefault(item => item.Properties != null && item.Properties.Contains(ManifestProperty.NAV)); if (navManifestItem == null) { if (package.EpubVersion == EpubVersion.EPUB_2) { return(null); } else { throw new Exception("EPUB parsing error: NAV item not found in EPUB manifest."); } } string navFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, navManifestItem.Href); ZipArchiveEntry navFileEntry = epubArchive.GetEntry(navFileEntryPath); if (navFileEntry == null) { throw new Exception($"EPUB parsing error: navigation file {navFileEntryPath} not found in archive."); } if (navFileEntry.Length > Int32.MaxValue) { throw new Exception($"EPUB parsing error: navigation file {navFileEntryPath} is larger than 2 Gb."); } XDocument navDocument; using (Stream containerStream = navFileEntry.Open()) { navDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false); } XNamespace xhtmlNamespace = navDocument.Root.Name.Namespace; XElement htmlNode = navDocument.Element(xhtmlNamespace + "html"); if (htmlNode == null) { throw new Exception("EPUB parsing error: navigation file does not contain html element."); } XElement bodyNode = htmlNode.Element(xhtmlNamespace + "body"); if (bodyNode == null) { throw new Exception("EPUB parsing error: navigation file does not contain body element."); } result.Navs = new List <Epub3Nav>(); string folder = ZipPathUtils.GetDirectoryPath(navManifestItem.Href); foreach (XElement navNode in bodyNode.Elements(xhtmlNamespace + "nav")) { Epub3Nav epub3Nav = ReadEpub3Nav(navNode); AdjustRelativePath(epub3Nav.Ol, folder); result.Navs.Add(epub3Nav); } return(result); }
private static Epub3Nav ReadEpub3Nav(XElement navNode) { Epub3Nav epub3Nav = new Epub3Nav(); foreach (XAttribute navNodeAttribute in navNode.Attributes()) { string attributeValue = navNodeAttribute.Value; switch (navNodeAttribute.GetLowerCaseLocalName()) { case "type": epub3Nav.Type = StructuralSemanticsPropertyParser.Parse(attributeValue); break; case "hidden": epub3Nav.IsHidden = true; break; } } foreach (XElement navChildNode in navNode.Elements()) { switch (navChildNode.GetLowerCaseLocalName()) { case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": epub3Nav.Head = navChildNode.Value.Trim(); break; case "ol": Epub3NavOl epub3NavOl = ReadEpub3NavOl(navChildNode); epub3Nav.Ol = epub3NavOl; break; } } return(epub3Nav); }
private static List <EpubNavigationItemRef> GetNavigationItems(EpubBookRef bookRef, Epub3Nav epub3Nav) { List <EpubNavigationItemRef> result; if (epub3Nav != null) { if (epub3Nav.Head != null) { result = new List <EpubNavigationItemRef>(); EpubNavigationItemRef navigationItemRef = EpubNavigationItemRef.CreateAsHeader(); navigationItemRef.Title = epub3Nav.Head; navigationItemRef.NestedItems = GetNavigationItems(bookRef, epub3Nav.Ol); result.Add(navigationItemRef); } else { result = GetNavigationItems(bookRef, epub3Nav.Ol); } } else { result = new List <EpubNavigationItemRef>(); } return(result); }