bool NavigationTable::ParseXML(xmlNodePtr node) { if ( node == nullptr ) return false; string name(node->name); if ( AllowedRootNodeNames.find(name) == AllowedRootNodeNames.end() ) return false; _type = _getProp(node, "type", ePub3NamespaceURI); if ( _type.empty() ) return false; #if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS) XPathWrangler xpath(node->doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors #else XPathWrangler::NamespaceList __ns; __ns["epub"] = ePub3NamespaceURI; XPathWrangler xpath(node->doc, __ns); #endif xpath.NameDefaultNamespace("html"); // look for optional <h2> title // Q: Should we fail on finding multiple <h2> tags here? auto strings = xpath.Strings("./html:h2[1]/text()", node); if ( !strings.empty() ) _title = std::move(strings[0]); // load List Elements from a single Ordered List // first: confirm there's a single list xmlNodeSetPtr nodes = xpath.Nodes("./html:ol", node); if ( nodes == nullptr ) return false; if ( nodes->nodeNr != 1 ) { xmlXPathFreeNodeSet(nodes); return false; } LoadChildElements(std::enable_shared_from_this<NavigationTable>::shared_from_this(), nodes->nodeTab[0]); xmlXPathFreeNodeSet(nodes); return true; }
bool NavigationTable::Parse(xmlNodePtr node) { if ( node == nullptr ) return false; string name(node->name); if ( AllowedRootNodeNames.find(name) == AllowedRootNodeNames.end() ) return false; _type = _getProp(node, "type", ePub3NamespaceURI); if ( _type.empty() ) return false; XPathWrangler xpath(node->doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors xpath.NameDefaultNamespace("html"); // look for optional <h2> title // Q: Should we fail on finding multiple <h2> tags here? auto strings = xpath.Strings("./html:h2[1]/text()", node); if ( !strings.empty() ) _title = std::move(strings[0]); // load List Elements from a single Ordered List // first: confirm there's a single list xmlNodeSetPtr nodes = xpath.Nodes("./html:ol", node); if ( nodes == nullptr ) return false; if ( nodes->nodeNr != 1 ) { xmlXPathFreeNodeSet(nodes); return false; } LoadChildElements(this, nodes->nodeTab[0]); xmlXPathFreeNodeSet(nodes); return true; }
shared_ptr<NavigationElement> NavigationTable::BuildNavigationPoint(xmlNodePtr liNode) { auto elementPtr = std::dynamic_pointer_cast<NavigationElement>(shared_from_this()); xmlNodePtr liChild = liNode->children; if(liChild == nullptr) { return nullptr; } auto point = std::make_shared<NavigationPoint>(elementPtr); for ( ; liChild != nullptr; liChild = liChild->next ) { if ( liChild->type != XML_ELEMENT_NODE ) continue; std::string cName(reinterpret_cast<const char*>(liChild->name)); if ( cName == "a" ) { point->SetTitle(reinterpret_cast<const char*>(xmlNodeGetContent(liChild))); point->SetContent(_getProp(liChild, "href")); } else if( cName == "span" ) { point->SetTitle(xmlNodeGetContent(liChild)); } else if( cName == "ol" ) { LoadChildElements(point, liChild); break; } } return point; }
NavigationElement* NavigationTable::BuildNavigationPoint(xmlNodePtr liNode) { xmlNodePtr liChild = liNode->children; if(liChild == nullptr) { return nullptr; } NavigationPoint* point = new NavigationPoint(); for ( ; liChild != nullptr; liChild = liChild->next ) { if ( liChild->type != XML_ELEMENT_NODE ) continue; std::string cName(reinterpret_cast<const char*>(liChild->name)); if ( cName == "a" ) { point->SetTitle(reinterpret_cast<const char*>(xmlNodeGetContent(liChild))); point->SetSourceHref(_getProp(liChild, "href")); } else if( cName == "span" ) { point->SetTitle(xmlNodeGetContent(liChild)); } else if( cName == "ol" ) { LoadChildElements(point, liChild); break; } } return point; }