修复解析一些epub3文件

一些epub3 的文件为了兼容epub2而保留了epub2的ncx目录导致解析目录失败。
pull/957/head
ag2s20150909 4 years ago
parent 937d4c61ef
commit b26cec93d0
  1. 6
      epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java
  2. 13
      epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java
  3. 38
      epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java
  4. 7
      epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java

@ -148,9 +148,9 @@ public class NCXDocumentV2 {
if (resource == null) {
Log.e(TAG, "Resource with href " + href + " in NCX document not found");
}
Log.d(TAG, "label:" + label);
Log.d(TAG, "href:" + href);
Log.d(TAG, "fragmentId:" + fragmentId);
Log.v(TAG, "label:" + label);
Log.v(TAG, "href:" + href);
Log.v(TAG, "fragmentId:" + fragmentId);
TOCReference result = new TOCReference(label, resource, fragmentId);
List<TOCReference> childTOCReferences = readTOCReferences(
navpointElement.getChildNodes(), book);

@ -107,12 +107,21 @@ public class NCXDocumentV3 {
if (ncxResource == null) {
return null;
}
//Log.d(TAG, ncxResource.getHref());
//一些epub 3 文件没有按照epub3的标准使用删除掉ncx目录文件
if (ncxResource.getHref().endsWith(".ncx")){
Log.v(TAG,"该epub文件不标准,使用了epub2的目录文件");
return NCXDocumentV2.read(book, epubReader);
}
Log.d(TAG, ncxResource.getHref());
Document ncxDocument = ResourceUtil.getAsDocument(ncxResource);
//Log.d(TAG, ncxDocument.getNodeName());
Log.d(TAG, ncxDocument.getNodeName());
Element navMapElement = (Element) ncxDocument.getElementsByTagName(XHTMLTgs.nav).item(0);
if(navMapElement==null){
Log.d(TAG,"epub3目录文件未发现nav节点,尝试使用epub2的规则解析");
return NCXDocumentV2.read(book, epubReader);
}
navMapElement = (Element) navMapElement.getElementsByTagName(XHTMLTgs.ol).item(0);
Log.d(TAG, navMapElement.getTagName());

@ -36,13 +36,12 @@ import me.ag2s.epublib.util.StringUtil;
* Reads the opf package document as defined by namespace http://www.idpf.org/2007/opf
*
* @author paul
*
*/
public class PackageDocumentReader extends PackageDocumentBase {
private static final String TAG= PackageDocumentReader.class.getName();
private static final String TAG = PackageDocumentReader.class.getName();
private static final String[] POSSIBLE_NCX_ITEM_IDS = new String[]{"toc",
"ncx", "ncxtoc","htmltoc"};
"ncx", "ncxtoc", "htmltoc"};
public static void read(
@ -56,7 +55,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
// Books sometimes use non-identifier ids. We map these here to legal ones
Map<String, String> idMapping = new HashMap<>();
String version=DOMUtil.getAttribute(packageDocument.getDocumentElement(),PREFIX_OPF,PackageDocumentBase.version);
String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version);
resources = readManifest(packageDocument, packageHref, epubReader,
resources, idMapping);
@ -119,18 +118,18 @@ public class PackageDocumentReader extends PackageDocumentBase {
try {
href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING);
} catch (UnsupportedEncodingException e) {
Log.e(TAG,e.getMessage());
Log.e(TAG, e.getMessage());
}
String mediaTypeName = DOMUtil
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.media_type);
Resource resource = resources.remove(href);
if (resource == null) {
Log.e(TAG,"resource with href '" + href + "' not found");
Log.e(TAG, "resource with href '" + href + "' not found");
continue;
}
resource.setId(id);
//for epub3
String properties=DOMUtil.getAttribute(itemElement,NAMESPACE_OPF,OPFAttributes.properties);
String properties = DOMUtil.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.properties);
resource.setProperties(properties);
MediaType mediaType = MediaTypes.getMediaTypeByName(mediaTypeName);
@ -175,14 +174,14 @@ public class PackageDocumentReader extends PackageDocumentBase {
Resource resource = resources.getByHref(StringUtil
.substringBefore(resourceHref, Constants.FRAGMENT_SEPARATOR_CHAR));
if (resource == null) {
Log.e(TAG,"Guide is referencing resource with href " + resourceHref
Log.e(TAG, "Guide is referencing resource with href " + resourceHref
+ " which could not be found");
continue;
}
String type = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.type);
if (StringUtil.isBlank(type)) {
Log.e(TAG,"Guide is referencing resource with href " + resourceHref
Log.e(TAG, "Guide is referencing resource with href " + resourceHref
+ " which is missing the 'type' attribute");
continue;
}
@ -201,7 +200,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
/**
* Strips off the package prefixes up to the href of the packageHref.
*
* <p>
* Example:
* If the packageHref is "OEBPS/content.opf" then a resource href like "OEBPS/foo/bar.html" will be turned into "foo/bar.html"
*
@ -241,7 +240,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
.getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
NAMESPACE_OPF, OPFTags.spine);
if (spineElement == null) {
Log.e(TAG,"Element " + OPFTags.spine
Log.e(TAG, "Element " + OPFTags.spine
+ " not found in package document, generating one automatically");
return generateSpineFromResources(resources);
}
@ -259,7 +258,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
String itemref = DOMUtil
.getAttribute(spineItem, NAMESPACE_OPF, OPFAttributes.idref);
if (StringUtil.isBlank(itemref)) {
Log.e(TAG,"itemref with missing or empty idref"); // XXX
Log.e(TAG, "itemref with missing or empty idref"); // XXX
continue;
}
String id = idMapping.get(itemref);
@ -308,7 +307,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
/**
* The spine tag should contain a 'toc' attribute with as value the resource id of the table of contents resource.
*
* <p>
* Here we try several ways of finding this table of contents resource.
* We try the given attribute value, some often-used ones and finally look through all resources for the first resource with the table of contents mimetype.
*
@ -318,7 +317,13 @@ public class PackageDocumentReader extends PackageDocumentBase {
*/
static Resource findTableOfContentsResource(String tocResourceId,
Resources resources) {
Resource tocResource = null;
Resource tocResource;
//一些epub3的文件为了兼容epub2,保留的epub2的目录文件,这里优先选择epub3的xml目录
tocResource = resources.getByProperties("nav");
if (tocResource != null) {
return tocResource;
}
if (StringUtil.isNotBlank(tocResourceId)) {
tocResource = resources.getByIdOrHref(tocResourceId);
}
@ -343,10 +348,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
}
}
}
//For EPUB3
if (tocResource==null){
tocResource=resources.getByProperties("nav");
}
if (tocResource == null) {
Log.e(TAG,

@ -1,5 +1,7 @@
package me.ag2s.epublib.util;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.EOFException;
@ -18,6 +20,7 @@ import java.nio.CharBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import me.ag2s.epublib.epub.PackageDocumentReader;
import me.ag2s.epublib.util.commons.io.IOConsumer;
/**
@ -28,6 +31,7 @@ import me.ag2s.epublib.util.commons.io.IOConsumer;
* and using my own implementation saves the inclusion of a 200Kb jar file.
*/
public class IOUtil {
private static final String TAG = IOUtil.class.getName();
/**
* Represents the end-of-file (or stream).
@ -146,7 +150,8 @@ public class IOUtil {
if(buffer>IOUtil.DEFAULT_BUFFER_SIZE||buffer==0){
buffer=IOUtil.DEFAULT_BUFFER_SIZE;
}
copy(in, result,buffer);
Log.d(TAG,"buffer size:"+buffer);
copy(in, result,DEFAULT_BUFFER_SIZE);
}
/**

Loading…
Cancel
Save