From 19f9ce0629754d3c379a7c9676d91ba69d4275d8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 19 Mar 2012 20:15:40 +0100 Subject: [PATCH] Sort filter using xpath result for sort criteria Sort order may be given in configuration. --- src/filter_sort.cpp | 71 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/src/filter_sort.cpp b/src/filter_sort.cpp index 700b638..c91d8a8 100644 --- a/src/filter_sort.cpp +++ b/src/filter_sort.cpp @@ -50,6 +50,7 @@ namespace metaproxy_1 { int m_prefetch; std::string m_xpath_expr; std::string m_namespaces; + bool m_ascending; boost::mutex m_mutex; boost::condition m_cond_session_ready; std::map m_clients; @@ -220,8 +221,30 @@ void yf::Sort::Record::get_xpath(xmlDoc *doc, const char *namespaces, xmlXPathEvalExpression((const xmlChar *) expr, xpathCtx); if (xpathObj) { - print_xpath_nodes(xpathObj->nodesetval, stdout); - + xmlNodeSetPtr nodes = xpathObj->nodesetval; + if (nodes) + { + int i; + for (i = 0; i < nodes->nodeNr; i++) + { + std::string content; + xmlNode *ptr = nodes->nodeTab[i]; + if (ptr->type == XML_ELEMENT_NODE || + ptr->type == XML_ATTRIBUTE_NODE) + { + content = mp::xml::get_text(ptr->children); + } + else if (ptr->type == XML_TEXT_NODE) + { + content = mp::xml::get_text(ptr); + } + if (content.c_str()) + { + score = content; + break; + } + } + } xmlXPathFreeObject(xpathObj); } xmlXPathFreeContext(xpathCtx); @@ -257,28 +280,9 @@ yf::Sort::Record::~Record() bool yf::Sort::Record::operator < (const Record &rhs) { - int l_score = 0; - const char *l_database = this->npr->databaseName; - if (l_database) - { - const char *cp = strstr(l_database, ";score="); - if (cp) - l_score = atoi(cp + 7); - } - - int r_score = 0; - const char *r_database = rhs.npr->databaseName; - if (r_database) - { - const char *cp = strstr(r_database, ";score="); - if (cp) - r_score = atoi(cp + 7); - } - - if (l_score < r_score) + if (strcmp(this->score.c_str(), rhs.score.c_str()) < 0) return true; - else - return false; + return false; } yf::Sort::RecordList::RecordList(Odr_oid *syntax, @@ -301,7 +305,6 @@ yf::Sort::RecordList::~RecordList() void yf::Sort::RecordList::add(Z_NamePlusRecord *s) { ODR oi = m_odr; - yaz_log(YLOG_LOG, "Adding to recordList %p", this); Record record(yaz_clone_z_NamePlusRecord(s, oi->mem), namespaces.c_str(), xpath_expr.c_str()); @@ -352,7 +355,7 @@ yf::Sort::Frontend::~Frontend() } -yf::Sort::Impl::Impl() : m_prefetch(20) +yf::Sort::Impl::Impl() : m_prefetch(20), m_ascending(true) { } @@ -435,6 +438,19 @@ void yf::Sort::Impl::configure(const xmlNode *ptr, bool test_only, { m_namespaces = mp::xml::get_text(attr->children); } + else if (!strcmp((const char *) attr->name, "sortorder")) + { + std::string t = mp::xml::get_text(attr->children); + if (t == "ascending") + m_ascending = true; + else if (t == "descending") + m_ascending = false; + else + throw mp::filter::FilterException( + "Bad attribute value " + t + " for attribute " + + std::string((const char *) attr->name)); + + } else throw mp::filter::FilterException( "Bad attribute " + @@ -518,7 +534,10 @@ void yf::Sort::Frontend::handle_records(mp::Package &package, rlp->sort(); for (i = 0; i < nprl->num_records; i++) - nprl->records[i] = rlp->get(i); + if (m_p->m_ascending) + nprl->records[i] = rlp->get(i); + else + nprl->records[nprl->num_records - i - 1] = rlp->get(i); } } -- 1.7.10.4