Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

...
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 2 contributors
Showing with 58 additions and 34 deletions.
  1. +12 −14 src/Epub.cpp
  2. +23 −15 src/Xml.cpp
  3. +23 −5 src/Xml.h
26 src/Epub.cpp
View
@@ -37,13 +37,14 @@ bool Epub::check() {
// read opf path from container
string container = zf->getFile("META-INF/container.xml");
Xml cx(container);
- vector<string> xr = cx.xpath("//rootfile/@full-path");
+ Xpath cp = cx.xpath();
+ vector<string> xr = cp.query("//rootfile/@full-path");
if(xr.size() == 0 ) return false;
string opfpath = xr[0];
base = opfpath.substr(0, opfpath.find_last_of('/')+1);
-
+
// parse opf
- Xml::nslist * ns = new Xml::nslist();
+ nslist * ns = new nslist();
string opfxml = zf->getFile(opfpath);
(*ns)[dcpref] = dcns;
@@ -52,26 +53,23 @@ bool Epub::check() {
string myopf = (opfxml.find("<item")==string::npos ? "//opf:" : "//");
Xml opf(opfxml);
- xr = opf.xpath(mydc+"title", ns);
- if(xr.size()) title = xr[0];
- xr = opf.xpath(mydc+"creator", ns);
- if(xr.size()) author = xr[0];
- xr = opf.xpath(mydc+"publisher", ns);
- if(xr.size()) publisher = xr[0];
- string coverId;
- xr = opf.xpath("//meta[@name='cover']/@content", ns);
+ Xpath ox = opf.xpath(ns);
+ title = ox.get(mydc+"title");
+ author = ox.get(mydc+"creator");
+ publisher = ox.get(mydc+"publisher");
+ string coverId = ox.get("//meta[@name='cover']/@content");
// Items:
// get //itemref/@idref and read the item's href
- xr = opf.xpath(myopf+"itemref/@idref", ns);
+ xr = ox.query(myopf+"itemref/@idref");
string ix;
vector<string> nestx;
for(vector<string>::iterator it = xr.begin(); it != xr.end(); ++it) {
ix = myopf+"item[@id='";
ix.append(*it);
ix.append("']/@href");
- nestx = opf.xpath(ix, ns);
+ nestx = ox.query(ix);
if(nestx.size()>0) {
items.push_back(nestx[0]);
if(it->compare(coverId) == 0) coverIndex = items.size()-1;
@@ -79,7 +77,7 @@ bool Epub::check() {
}
// Resources:
// <item> not in vector items
- xr = opf.xpath(myopf+"item/@href", ns);
+ xr = ox.query(myopf+"item/@href");
for(vector<string>::iterator it = xr.begin(); it != xr.end(); ++it) {
if(std::find(items.begin(), items.end(), *it) == items.end())
resources.push_back(*it);
38 src/Xml.cpp
View
@@ -7,10 +7,6 @@
*/
#include "Xml.h"
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <string.h>
bool Xml::initDone = Xml::doInit();
@@ -32,19 +28,11 @@ Xml::Xml(string xmlstring) {
"Xml.xml", "UTF-8", XML_PARSE_RECOVER | XML_PARSE_NONET );
}
-std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
+std::vector<string> Xpath::query(string expr) {
std::vector<string> res;
- if(!isValid()) return res;
- xmlXPathContext * context = xmlXPathNewContext(doc);
if(!context) {
return res;
}
- //register namespaces
- if(xns)
- for ( Xml::nslist::iterator it=xns->begin() ; it != xns->end(); it++ ) {
- xmlXPathRegisterNs(context,
- (xmlChar*)it->first.c_str() , (xmlChar*)it->second.c_str());
- }
xmlXPathObject * result = xmlXPathEvalExpression((xmlChar*)expr.c_str(), context);
@@ -55,7 +43,7 @@ std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
else if(result->type == XPATH_NODESET) {
nodeset = result->nodesetval;
if (nodeset) for (int i=0; i < nodeset->nodeNr; i++) {
- nsi = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
+ nsi = xmlNodeListGetString(context->doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
res.push_back((char *)nsi);
xmlFree(nsi);
}
@@ -63,10 +51,30 @@ std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
}
xmlXPathFreeObject(result);
- xmlXPathFreeContext(context);
return res;
}
+string Xpath::get(string expr) {
+ std::vector<string> res = query(expr);
+ if(res.size()) return res[0];
+ return "";
+}
+
Xml::~Xml() {
if(doc) xmlFreeDoc(doc);
}
+
+
+Xpath::Xpath(xmlDoc * doc, nslist * ns) {
+ context = xmlXPathNewContext(doc);
+
+ if(ns && context)
+ for ( nslist::iterator it=ns->begin() ; it != ns->end(); it++ ) {
+ xmlXPathRegisterNs(context,
+ (xmlChar*)it->first.c_str() , (xmlChar*)it->second.c_str());
+ }
+}
+
+Xpath::~Xpath() {
+ if(context) xmlXPathFreeContext(context);
+}
28 src/Xml.h
View
@@ -13,22 +13,40 @@
#include <map>
#include <vector>
#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
using std::string;
+typedef std::map<string, string> nslist;
+
+class Xpath {
+ friend class Xml;
+public:
+ std::vector<string> query(string expr);
+ string get(string expr);
+
+ ~Xpath();
+
+private:
+ Xpath(xmlDoc * doc, nslist * ns);
+
+ xmlXPathContext * context;
+
+};
+
class Xml {
public:
- typedef struct {
+/* typedef struct {
string value, name;
std::map<string, string> attributes;
} Element;
-
- typedef std::map<string, string> nslist;
-
+*/
+
Xml(string xmlstring);
bool isValid() { return doc!=NULL; }
- std::vector<string> xpath(string expr, nslist * xns = NULL);
+ Xpath xpath(nslist * ns = NULL) { return Xpath(doc, ns); }
virtual ~Xml();

No commit comments for this range

Something went wrong with that request. Please try again.