Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 3 files changed
  • 0 comments
  • 2 contributors

Showing 3 changed files with 58 additions and 34 deletions. Show diff stats Hide diff stats

  1. +12 14 src/Epub.cpp
  2. +23 15 src/Xml.cpp
  3. +23 5 src/Xml.h
26 src/Epub.cpp
@@ -37,13 +37,14 @@ bool Epub::check() {
37 37 // read opf path from container
38 38 string container = zf->getFile("META-INF/container.xml");
39 39 Xml cx(container);
40   - vector<string> xr = cx.xpath("//rootfile/@full-path");
  40 + Xpath cp = cx.xpath();
  41 + vector<string> xr = cp.query("//rootfile/@full-path");
41 42 if(xr.size() == 0 ) return false;
42 43 string opfpath = xr[0];
43 44 base = opfpath.substr(0, opfpath.find_last_of('/')+1);
44   -
  45 +
45 46 // parse opf
46   - Xml::nslist * ns = new Xml::nslist();
  47 + nslist * ns = new nslist();
47 48
48 49 string opfxml = zf->getFile(opfpath);
49 50 (*ns)[dcpref] = dcns;
@@ -52,26 +53,23 @@ bool Epub::check() {
52 53 string myopf = (opfxml.find("<item")==string::npos ? "//opf:" : "//");
53 54
54 55 Xml opf(opfxml);
55   - xr = opf.xpath(mydc+"title", ns);
56   - if(xr.size()) title = xr[0];
57   - xr = opf.xpath(mydc+"creator", ns);
58   - if(xr.size()) author = xr[0];
59   - xr = opf.xpath(mydc+"publisher", ns);
60   - if(xr.size()) publisher = xr[0];
61   - string coverId;
62   - xr = opf.xpath("//meta[@name='cover']/@content", ns);
  56 + Xpath ox = opf.xpath(ns);
  57 + title = ox.get(mydc+"title");
  58 + author = ox.get(mydc+"creator");
  59 + publisher = ox.get(mydc+"publisher");
  60 + string coverId = ox.get("//meta[@name='cover']/@content");
63 61
64 62 // Items:
65 63 // get //itemref/@idref and read the item's href
66 64
67   - xr = opf.xpath(myopf+"itemref/@idref", ns);
  65 + xr = ox.query(myopf+"itemref/@idref");
68 66 string ix;
69 67 vector<string> nestx;
70 68 for(vector<string>::iterator it = xr.begin(); it != xr.end(); ++it) {
71 69 ix = myopf+"item[@id='";
72 70 ix.append(*it);
73 71 ix.append("']/@href");
74   - nestx = opf.xpath(ix, ns);
  72 + nestx = ox.query(ix);
75 73 if(nestx.size()>0) {
76 74 items.push_back(nestx[0]);
77 75 if(it->compare(coverId) == 0) coverIndex = items.size()-1;
@@ -79,7 +77,7 @@ bool Epub::check() {
79 77 }
80 78 // Resources:
81 79 // <item> not in vector items
82   - xr = opf.xpath(myopf+"item/@href", ns);
  80 + xr = ox.query(myopf+"item/@href");
83 81 for(vector<string>::iterator it = xr.begin(); it != xr.end(); ++it) {
84 82 if(std::find(items.begin(), items.end(), *it) == items.end())
85 83 resources.push_back(*it);
38 src/Xml.cpp
@@ -7,10 +7,6 @@
7 7 */
8 8
9 9 #include "Xml.h"
10   -#include <libxml/tree.h>
11   -#include <libxml/xpath.h>
12   -#include <libxml/xpathInternals.h>
13   -#include <string.h>
14 10
15 11 bool Xml::initDone = Xml::doInit();
16 12
@@ -32,19 +28,11 @@ Xml::Xml(string xmlstring) {
32 28 "Xml.xml", "UTF-8", XML_PARSE_RECOVER | XML_PARSE_NONET );
33 29 }
34 30
35   -std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
  31 +std::vector<string> Xpath::query(string expr) {
36 32 std::vector<string> res;
37   - if(!isValid()) return res;
38   - xmlXPathContext * context = xmlXPathNewContext(doc);
39 33 if(!context) {
40 34 return res;
41 35 }
42   - //register namespaces
43   - if(xns)
44   - for ( Xml::nslist::iterator it=xns->begin() ; it != xns->end(); it++ ) {
45   - xmlXPathRegisterNs(context,
46   - (xmlChar*)it->first.c_str() , (xmlChar*)it->second.c_str());
47   - }
48 36
49 37 xmlXPathObject * result = xmlXPathEvalExpression((xmlChar*)expr.c_str(), context);
50 38
@@ -55,7 +43,7 @@ std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
55 43 else if(result->type == XPATH_NODESET) {
56 44 nodeset = result->nodesetval;
57 45 if (nodeset) for (int i=0; i < nodeset->nodeNr; i++) {
58   - nsi = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
  46 + nsi = xmlNodeListGetString(context->doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
59 47 res.push_back((char *)nsi);
60 48 xmlFree(nsi);
61 49 }
@@ -63,10 +51,30 @@ std::vector<string> Xml::xpath(string expr, Xml::nslist * xns) {
63 51 }
64 52
65 53 xmlXPathFreeObject(result);
66   - xmlXPathFreeContext(context);
67 54 return res;
68 55 }
69 56
  57 +string Xpath::get(string expr) {
  58 + std::vector<string> res = query(expr);
  59 + if(res.size()) return res[0];
  60 + return "";
  61 +}
  62 +
70 63 Xml::~Xml() {
71 64 if(doc) xmlFreeDoc(doc);
72 65 }
  66 +
  67 +
  68 +Xpath::Xpath(xmlDoc * doc, nslist * ns) {
  69 + context = xmlXPathNewContext(doc);
  70 +
  71 + if(ns && context)
  72 + for ( nslist::iterator it=ns->begin() ; it != ns->end(); it++ ) {
  73 + xmlXPathRegisterNs(context,
  74 + (xmlChar*)it->first.c_str() , (xmlChar*)it->second.c_str());
  75 + }
  76 +}
  77 +
  78 +Xpath::~Xpath() {
  79 + if(context) xmlXPathFreeContext(context);
  80 +}
28 src/Xml.h
@@ -13,22 +13,40 @@
13 13 #include <map>
14 14 #include <vector>
15 15 #include <libxml/parser.h>
  16 +#include <libxml/xpath.h>
  17 +#include <libxml/xpathInternals.h>
16 18
17 19 using std::string;
18 20
  21 +typedef std::map<string, string> nslist;
  22 +
  23 +class Xpath {
  24 + friend class Xml;
  25 +public:
  26 + std::vector<string> query(string expr);
  27 + string get(string expr);
  28 +
  29 + ~Xpath();
  30 +
  31 +private:
  32 + Xpath(xmlDoc * doc, nslist * ns);
  33 +
  34 + xmlXPathContext * context;
  35 +
  36 +};
  37 +
19 38 class Xml {
20 39 public:
21   - typedef struct {
  40 +/* typedef struct {
22 41 string value, name;
23 42 std::map<string, string> attributes;
24 43 } Element;
25   -
26   - typedef std::map<string, string> nslist;
27   -
  44 +*/
  45 +
28 46 Xml(string xmlstring);
29 47
30 48 bool isValid() { return doc!=NULL; }
31   - std::vector<string> xpath(string expr, nslist * xns = NULL);
  49 + Xpath xpath(nslist * ns = NULL) { return Xpath(doc, ns); }
32 50
33 51 virtual ~Xml();
34 52

No commit comments for this range

Something went wrong with that request. Please try again.