private static EpubManifest ReadManifest(XmlNode manifestNode) { EpubManifest result = new EpubManifest(); foreach (XmlNode manifestItemNode in manifestNode.ChildNodes) { if (String.Compare(manifestItemNode.LocalName, "item", StringComparison.OrdinalIgnoreCase) == 0) { EpubManifestItem manifestItem = new EpubManifestItem(); foreach (XmlAttribute manifestItemNodeAttribute in manifestItemNode.Attributes) { string attributeValue = manifestItemNodeAttribute.Value; switch (manifestItemNodeAttribute.Name.ToLowerInvariant()) { case "id": manifestItem.Id = attributeValue; break; case "href": manifestItem.Href = attributeValue; break; case "media-type": manifestItem.MediaType = attributeValue; break; case "required-namespace": manifestItem.RequiredNamespace = attributeValue; break; case "required-modules": manifestItem.RequiredModules = attributeValue; break; case "fallback": manifestItem.Fallback = attributeValue; break; case "fallback-style": manifestItem.FallbackStyle = attributeValue; break; } } if (String.IsNullOrWhiteSpace(manifestItem.Id)) { throw new Exception("Incorrect EPUB manifest: item ID is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.Href)) { throw new Exception("Incorrect EPUB manifest: item href is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.MediaType)) { throw new Exception("Incorrect EPUB manifest: item media type is missing"); } result.Add(manifestItem); } } return(result); }
private static Image LoadCoverImage(EpubBook book) { List <EpubMetadataMeta> metaItems = book.Schema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing"); } EpubManifestItem coverManifestItem = book.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0); if (coverManifestItem == null) { throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing", coverMetaItem.Content)); } EpubByteContentFile coverImageContentFile; if (!book.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFile)) { throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing", coverManifestItem.Href)); } using (MemoryStream coverImageStream = new MemoryStream(coverImageContentFile.Content)) return(Image.FromStream(coverImageStream)); }
public static async Task <byte[]> ReadBookCoverAsync(EpubBookRef bookRef) { List <EpubMetadataMeta> metaItems = bookRef.Schema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing."); } EpubManifestItem coverManifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0); if (coverManifestItem == null) { throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing.", coverMetaItem.Content)); } if (!bookRef.Content.Images.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef)) { throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing.", coverManifestItem.Href)); } byte[] coverImageContent = await coverImageContentFileRef.ReadContentAsBytesAsync().ConfigureAwait(false); return(coverImageContent); }
public static EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs) { List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover")); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing."); } EpubManifestItem coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (coverManifestItem == null) { throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing."); } if (!imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef)) { throw new Exception($"Incorrect EPUB manifest: item with href = \"{coverManifestItem.Href}\" is missing."); } return(coverImageContentFileRef); }
public static List <EpubTextContentFileRef> GetReadingOrder(EpubBookRef bookRef) { List <EpubTextContentFileRef> result = new List <EpubTextContentFileRef>(); foreach (EpubSpineItemRef spineItemRef in bookRef.Schema.Package.Spine) { EpubManifestItem manifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(item => item.Id == spineItemRef.IdRef); if (manifestItem == null) { throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is missing in the manifest."); } if (bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef)) { result.Add(htmlContentFileRef); continue; } // 2019-08-21 Fix: some ebooks seem to contain two items with id="cover", one of them is an image, and the other an XHTML file // thus, if the first attempt to get the HTML item fails, we try for a second item with the same Id manifestItem = bookRef.Schema.Package.Manifest.Where(item => item.Id == spineItemRef.IdRef).Skip(1).FirstOrDefault(); if (manifestItem == null) { throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is not HTML content"); } if (bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef2)) { result.Add(htmlContentFileRef2); continue; } throw new Exception($"Incorrect EPUB manifest: item with href = \"{spineItemRef.IdRef}\" is missing in the book."); } return(result); }
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); }
public static EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs) { List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover")); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing."); } EpubManifestItem coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (coverManifestItem == null) { // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly! coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (null == coverManifestItem) { throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing."); } } if (imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef)) { return(coverImageContentFileRef); } // 2019-08-21 Fix some ebooks seem to contain more than one item with Id="cover" // thus we test if there is a second item.... coverManifestItem = epubSchema.Package.Manifest.Where(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)).Skip(1).FirstOrDefault();; if (coverManifestItem == null) { // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly! coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (null == coverManifestItem) { throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing."); } } if (imageContentRefs.TryGetValue(coverManifestItem.Href, out EpubByteContentFileRef coverImageContentFileRef2)) { return(coverImageContentFileRef2); } throw new Exception($"Incorrect EPUB manifest: item with href = \"{coverManifestItem.Href}\" is missing."); }
public static async Task <Image> ReadBookCoverAsync(EpubBookRef bookRef) { List <EpubMetadataMeta> metaItems = bookRef.Schema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => string.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing."); } EpubManifestItem coverManifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0); if (coverManifestItem == null) { throw new Exception(string.Format(CultureInfo.InvariantCulture, "Incorrect EPUB manifest: item with ID = \"{0}\" is missing.", coverMetaItem.Content)); } EpubByteContentFileRef coverImageContentFileRef; if (!bookRef.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef)) { throw new Exception(string.Format(CultureInfo.InvariantCulture, "Incorrect EPUB manifest: item with href = \"{0}\" is missing.", coverManifestItem.Href)); } byte[] coverImageContent = await coverImageContentFileRef.ReadContentAsBytesAsync().ConfigureAwait(false); using (MemoryStream coverImageStream = new MemoryStream(coverImageContent)) { Image image = new Image(); //return await Task.Run(() => Image.FromStream(coverImageStream)).ConfigureAwait(false); Func <Stream> stream = () => coverImageStream; image.Source = ImageSource.FromStream(stream); return(await Task.Run(() => image).ConfigureAwait(false)); } }
public static List <EpubTextContentFileRef> GetReadingOrder(EpubBookRef bookRef) { List <EpubTextContentFileRef> result = new List <EpubTextContentFileRef>(); foreach (EpubSpineItemRef spineItemRef in bookRef.Schema.Package.Spine) { EpubManifestItem manifestItem = bookRef.Schema.Package.Manifest.FirstOrDefault(item => item.Id == spineItemRef.IdRef); if (manifestItem == null) { throw new Exception($"Incorrect EPUB spine: item with IdRef = \"{spineItemRef.IdRef}\" is missing in the manifest."); } if (!bookRef.Content.Html.TryGetValue(manifestItem.Href, out EpubTextContentFileRef htmlContentFileRef)) { throw new Exception($"Incorrect EPUB manifest: item with href = \"{spineItemRef.IdRef}\" is missing in the book."); } result.Add(htmlContentFileRef); } return(result); }
private static async Task <BitmapImage> LoadCoverImageAsync(EpubBook book) { //TO-DO Currently this function only accepts covers as a image file. If cover is wrapped in.xhtml file - nothing happen. List <EpubMetadataMeta> metaItems = book.Schema.Package.Metadata.MetaItems; BitmapImage result = new BitmapImage(); if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => String.Compare(metaItem.Name, "cover", StringComparison.OrdinalIgnoreCase) == 0); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing"); } EpubManifestItem coverManifestItem = book.Schema.Package.Manifest.FirstOrDefault(manifestItem => String.Compare(manifestItem.Id, coverMetaItem.Content, StringComparison.OrdinalIgnoreCase) == 0); if (coverManifestItem == null) { throw new Exception(String.Format("Incorrect EPUB manifest: item with ID = \"{0}\" is missing", coverMetaItem.Content)); } EpubByteContentFile coverImageContentFile; // --------------------------------------------------------------------------------------------------------------------- //TO-DO: Currently this function only accepts covers as a image file. If cover is wrapped in.xhtml file - nothing happen. // Have to check how people using wrapped cover - do they point <meta content> directly to xhtml or just placing it in the manifest // --------------------------------------------------------------------------------------------------------------------- if (!book.Content.Images.TryGetValue(coverManifestItem.Href, out coverImageContentFile)) { throw new Exception(String.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing", coverManifestItem.Href)); } // Old code is not working as SystemDrawings is deprecated //using (MemoryStream coverImageStream = new MemoryStream(coverImageContentFile.Content)) result = await ConvertToBitmapImageAsync(coverImageContentFile.Content); return(result); }
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 EpubByteContentFileRef ReadBookCover(EpubSchema epubSchema, Dictionary <string, EpubByteContentFileRef> imageContentRefs) { List <EpubMetadataMeta> metaItems = epubSchema.Package.Metadata.MetaItems; if (metaItems == null || !metaItems.Any()) { return(null); } EpubMetadataMeta coverMetaItem = metaItems.FirstOrDefault(metaItem => metaItem.Name.CompareOrdinalIgnoreCase("cover")); if (coverMetaItem == null) { return(null); } if (String.IsNullOrEmpty(coverMetaItem.Content)) { throw new Exception("Incorrect EPUB metadata: cover item content is missing."); } EpubByteContentFileRef coverImageContentFileRef; EpubManifestItem coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef)) { return(coverImageContentFileRef); } // For non-standard ebooks, we try several other ways... if (null != coverManifestItem) // we have found the item but there was no corresponding image ... { // some ebooks seem to contain more than one item with Id="cover" // thus we test if there is a second item, and whether that is an image.... coverManifestItem = epubSchema.Package.Manifest.Where(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Content)).Skip(1).FirstOrDefault();; if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef)) { return(coverImageContentFileRef); } } // we have still not found the item // 2019-08-20 Hotfix: if coverManifestItem is not found by its Id, then try it with its Href - some ebooks refer to the image directly! coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Href.CompareOrdinalIgnoreCase(coverMetaItem.Content)); if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef)) { return(coverImageContentFileRef); } // 2019-08-24 if it is still not found, then try to find an Id named cover coverManifestItem = epubSchema.Package.Manifest.FirstOrDefault(manifestItem => manifestItem.Id.CompareOrdinalIgnoreCase(coverMetaItem.Name)); if (null != coverManifestItem?.Href && imageContentRefs.TryGetValue(coverManifestItem.Href, out coverImageContentFileRef)) { return(coverImageContentFileRef); } // 2019-08-24 if it is still not found, then try to find it in the guide var guideItem = epubSchema.Package.Guide.FirstOrDefault(reference => reference.Title.CompareOrdinalIgnoreCase(coverMetaItem.Name)); if (null != guideItem?.Href && imageContentRefs.TryGetValue(guideItem.Href, out coverImageContentFileRef)) { return(coverImageContentFileRef); } throw new Exception($"Incorrect EPUB manifest: item with ID = \"{coverMetaItem.Content}\" is missing or no corresponding image was found."); }
public static async Task <EpubNavigation> ReadNavigationAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package) { EpubNavigation result = new EpubNavigation(); string tocId = package.Spine.Toc; XmlReaderSettings xmlReaderSettings = new XmlReaderSettings { // XmlResolver = null, Async = true, DtdProcessing = DtdProcessing.Ignore }; if (String.IsNullOrEmpty(tocId)) { throw new Exception("EPUB parsing error: TOC ID is empty."); } //Cheking if toc id referenced in spine exist in manifest 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)); } //Opening .toc file in archive using href-reference from manifest 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)); } // ------------------ Actual Parsing starts here: ------------------------- using (Stream containerStream = tocFileEntry.Open()) { using (XmlReader xmlReader = XmlReader.Create(containerStream, xmlReaderSettings)) { result.Head = await ReadNavigationHeadAsync(xmlReader); result.DocTitle = await ReadNavigationDocTitleAsync(xmlReader); result.DocAuthors = await ReadNavigationAuthorsAsync(xmlReader); result.NavMap = await ReadNavigationMapAsync(xmlReader); result.NavLists = new List <EpubNavigationList>(); //Empty, because not implemented result.PageList = new EpubNavigationPageList(); //Empty, because not implemented } } return(result); //-------------------------------------------Boring old style Silverlight code...----------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------------------------------------ //XmlDocument containerDocument; //containerDocument = XmlDocument.Load(containerStream); //XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(containerDocument.NameTable); //xmlNamespaceManager.AddNamespace("ncx", "http://www.daisy.org/z3986/2005/ncx/"); ////Parsing head section //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; ////Parsing title //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; ////Parsing authors section... //result.DocAuthors = new List<EpubNavigationDocAuthor>(); //foreach (XmlNode docAuthorNode in containerDocument.DocumentElement.SelectNodes("ncx:docAuthor", xmlNamespaceManager)) //{ // EpubNavigationDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode); // result.DocAuthors.Add(navigationDocAuthor); //} //Parsing navMap section //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; //-----------------------------------TO-DO: Implement ----------------------------------------------------------- //TO-DO: Implement pageList parsing. Needed to tide-up position inside epub to actual pages of the printed book //-------------------------------------------------------------------------------------------------------------- //Parsing pageList node //XmlNode pageListNode = containerDocument.DocumentElement.SelectSingleNode("ncx:pageList", xmlNamespaceManager); //if (pageListNode != null) //{ // EpubNavigationPageList pageList = ReadNavigationPageList(pageListNode); // result.PageList = pageList; //} ////TO-DO: Implement navList parsing. It is a secondary navigation system for supplied book info - schemes, fugures, diagrams, illustrations etc ////Parsing navList nodes //result.NavLists = new List<EpubNavigationList>(); //foreach (XmlNode navigationListNode in containerDocument.DocumentElement.SelectNodes("ncx:navList", xmlNamespaceManager)) //{ // EpubNavigationList navigationList = ReadNavigationList(navigationListNode); // result.NavLists.Add(navigationList); //} //-------------------------------------------------------------------------------------------------------------- }
private static EpubManifest ReadManifest(XElement manifestNode) { EpubManifest result = new EpubManifest(); foreach (XElement manifestItemNode in manifestNode.Elements()) { if (manifestItemNode.CompareNameTo("item")) { EpubManifestItem manifestItem = new EpubManifestItem(); foreach (XAttribute manifestItemNodeAttribute in manifestItemNode.Attributes()) { string attributeValue = manifestItemNodeAttribute.Value; switch (manifestItemNodeAttribute.GetLowerCaseLocalName()) { case "id": manifestItem.Id = attributeValue; break; case "href": manifestItem.Href = Uri.UnescapeDataString(attributeValue); break; case "media-type": manifestItem.MediaType = attributeValue; break; case "required-namespace": manifestItem.RequiredNamespace = attributeValue; break; case "required-modules": manifestItem.RequiredModules = attributeValue; break; case "fallback": manifestItem.Fallback = attributeValue; break; case "fallback-style": manifestItem.FallbackStyle = attributeValue; break; case "properties": manifestItem.Properties = ReadManifestProperties(attributeValue); break; } } if (String.IsNullOrWhiteSpace(manifestItem.Id)) { throw new Exception("Incorrect EPUB manifest: item ID is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.Href)) { throw new Exception("Incorrect EPUB manifest: item href is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.MediaType)) { throw new Exception("Incorrect EPUB manifest: item media type is missing"); } result.Add(manifestItem); } } return(result); }
private static async System.Threading.Tasks.Task <EpubManifest> ReadManifestAsync(XmlReader reader) { EpubManifest result = new EpubManifest(); bool isManifestFound = await reader.ReadToFollowingAsync("manifest", "http://www.idpf.org/2007/opf"); if (!isManifestFound) { throw new Exception("EPUB parsing error: manifest declarations not found in the package."); } while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "manifest")) { if (!String.IsNullOrWhiteSpace(reader.LocalName)) { EpubManifestItem manifestItem = new EpubManifestItem(); switch (reader.LocalName.ToLowerInvariant()) { case "item": while (reader.MoveToNextAttribute()) { switch (reader.LocalName.ToLowerInvariant()) { case "id": manifestItem.Id = reader.Value; break; case "href": manifestItem.Href = reader.Value; break; case "media-type": manifestItem.MediaType = reader.Value; break; case "required-namespace": manifestItem.RequiredNamespace = reader.Value; break; case "required-modules": manifestItem.RequiredModules = reader.Value; break; case "fallback": manifestItem.Fallback = reader.Value; break; case "fallback-style": manifestItem.FallbackStyle = reader.Value; break; } } break; } if (String.IsNullOrWhiteSpace(manifestItem.Id)) { throw new Exception("Incorrect EPUB manifest: item ID is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.Href)) { throw new Exception("Incorrect EPUB manifest: item href is missing"); } if (String.IsNullOrWhiteSpace(manifestItem.MediaType)) { throw new Exception("Incorrect EPUB manifest: item media type is missing"); } result.Add(manifestItem); } } 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); }