1 package org.readium.r2_streamer.parser;
3 import org.readium.r2_streamer.model.container.Container;
4 import org.readium.r2_streamer.model.publication.EpubPublication;
5 import org.readium.r2_streamer.model.tableofcontents.TOCLink;
7 import org.w3c.dom.Document;
8 import org.w3c.dom.Element;
9 import org.w3c.dom.Node;
11 import java.util.ArrayList;
12 import java.util.List;
15 * Created by gautam chibde on 31/5/17.
18 public class NCXParser {
20 private static final String TAG = NCXParser.class.getSimpleName();
22 public static void parseNCXFile(String ncxFile, Container container, EpubPublication publication, String rootPath) throws EpubParserException {
23 String ncxData = container.rawData(ncxFile);
24 if (ncxData == null) {
25 return; // File is missing
27 Document document = EpubParser.xmlParser(ncxData);
28 if (document == null) {
29 throw new EpubParserException("Error while parsing");
32 Element navMapElement = (Element) document.getElementsByTagName("navMap").item(0);
33 // Parse table of contents (toc) from ncx file
34 if (navMapElement != null) {
35 publication.tableOfContents = nodeArray(navMapElement, "navPoint", rootPath);
38 Element pageList = (Element) document.getElementsByTagName("pageList").item(0);
39 // Parse page list if exists from ncx file
40 if (pageList != null) {
41 publication.pageList = nodeArray(pageList, "pageTarget", rootPath);
46 * Generate an array of {@link TOCLink} elements representation of the XML
47 * structure in the ncx file. Each of them possibly having children.
49 * @param elements NCX DOM element object
50 * @param type The sub elements names (e.g. 'navPoint' for 'navMap',
51 * 'pageTarget' for 'pageList'.
52 * @return The Object representation of the data contained in the given NCX XML element.
54 private static List<TOCLink> nodeArray(Element elements, String type, String rootPath) {
55 // The "to be returned" node array.
56 List<TOCLink> newNodeArray = new ArrayList<>();
58 // Find the elements of `type` in the XML element.
59 for (Node n = elements.getFirstChild(); n != null; n = n.getNextSibling()) {
60 if (n.getNodeType() == Node.ELEMENT_NODE) {
61 Element e = (Element) n;
62 if (e.getTagName().equalsIgnoreCase(type)) {
63 newNodeArray.add(node(e, type, rootPath));
72 * Create a node link from the specified type element.
73 * recur if there are child elements
75 * @param element the DOM NCX file elemet
76 * @param type The sub elements names (e.g. 'navPoint' for 'navMap',
77 * 'pageTarget' for 'pageList'.
78 * @return The generated node {@link TOCLink}.
80 private static TOCLink node(Element element, String type, String rootPath) {
81 TOCLink newNode = new TOCLink();
83 Element content = (Element) element.getElementsByTagName("content").item(0);
84 Element navLabel = (Element) element.getElementsByTagName("navLabel").item(0);
85 if (content != null) {
86 newNode.href = rootPath + content.getAttribute("src");
88 if (navLabel != null) {
89 Element text = (Element) navLabel.getElementsByTagName("text").item(0);
91 newNode.bookTitle = text.getTextContent();
95 for (Node n = element.getFirstChild(); n != null; n = n.getNextSibling()) {
96 if (n.getNodeType() == Node.ELEMENT_NODE) {
97 Element e = (Element) n;
98 if (e.getTagName().equalsIgnoreCase(type)) {
99 newNode.tocLinks.add(node(e, type, rootPath));