树数据结构的实际应用

电子书目录读取

由来

​ 在epub2规范生成的epub电子书中负责目录导航的文件toc.nxc文件,但是在epub3规范生成的电子书中负责目录导航的文件是toc.xhtml文件。公司的移动端的SDK并不支持toc.xhtml文件的电子书目录导航。我这边需要将toc.xhtml文件转换成toc.ncx文件。

工具准备

  1. 读取电子书文档的jar包 (epublib-core)
  2. 对html文档进行解析操作的jar (Jsoup)

导入maven依赖

		<!-- https://mvnrepository.com/artifact/nl.siegmann.epublib/epublib-core -->
		<dependency>
        <groupId>nl.siegmann.epublib</groupId>
        <artifactId>epublib-core</artifactId>
        <version>3.1</version>
        </dependency>
		<!-- https://mvnrepository.com/artifact/net.sf.kxml/kxml2 -->
		<dependency>
			<groupId>net.sf.kxml</groupId>
			<artifactId>kxml2</artifactId>
			<version>2.3.0</version>
		</dependency>
		
		
		<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
		<dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.8.3</version>
		</dependency>

代码思路

  1. 目录结构抽象成Jave中的数据模型。很明显是树数据结构
  2. 利用递归进行数据解析

代码实现

主要核心代码如下:

  		// 读取电子书
  		Book book = epubReader.readEpub(inputStream);
 // 获取电子书目录
        TableOfContents tableOfContents = book.getTableOfContents();
           if (tableOfContents != null && tableOfContents.size() <=0 && !book.getNcxResource().getHref().contains("toc.ncx") ) {
            String data = new String(book.getResources().getById("ncx").getData(), "UTF-8");
            // 用Jsoup 生成文档格式
            Document document = Jsoup.parse(data);
            List<TOCReference> tocReferenceList = new ArrayList<>();
            for (String resourceId : resourceIds) {
                // 获取目录结构
                Element element = document.select("nav#toc").select("a[href=" + resourceId + ".xhtml]").parents().first();
                Elements elements = new Elements(element);
                // 获取该章下得所有目录
                List<TOCReference> referenceList = EbookCatalogUtil.getChapterCalog(elements, book.getResources().getById(resourceId));
                tocReferenceList.add(referenceList.get(0));

            }
            // 给目录添加属性
            tableOfContents.setTocReferences(tocReferenceList);
        }
        

EbookCatalogUtil工具类:

 /**
     * @Author ouyangkang
     * @Description 获取章节目录
     * @Date 10:24 2018/11/2
     * @param elements
     * @return java.util.List<com.zhihuishu.ebook.util.EbookCatalogUtil.ChapterCatalog>
    **/
    public static List<TOCReference> getChapterCalog(Elements elements, Resource resource){
        List<TOCReference> list = new LinkedList<>();
        for (Element element : elements){
            // 获取该章节ID
            String resourceId = element.attributes().get("id");
            // 获取该章节名字
            String name = element.select("#"+resourceId+"> a").text();
            // 获取孩子 element
            Elements elementsTemp = element.select("#" + resourceId + " > ol > li");

            TOCReference tocReference = new TOCReference();

            tocReference.setTitle(name);

            tocReference.setResource(resource);

            tocReference.setFragmentId(UUID.randomUUID().toString());
            //递归调用设置孩子节点
            tocReference.setChildren(getChapterCalog(elementsTemp, resource));

            list.add(tocReference);
        }
        return list;

    }
posted @ 2018-11-02 16:04  家里那只橘猫  阅读(412)  评论(0编辑  收藏  举报