diff options
Diffstat (limited to 'src/xpath.cc')
-rw-r--r-- | src/xpath.cc | 83 |
1 files changed, 32 insertions, 51 deletions
diff --git a/src/xpath.cc b/src/xpath.cc index a59126ae..caa7806a 100644 --- a/src/xpath.cc +++ b/src/xpath.cc @@ -562,7 +562,7 @@ bool xpath_t::function_scope_t::resolve(const string& name, case 't': if (name == "text") { if (value->type == value_t::XML_NODE) - result.set_string(value->as_xml_node()->text()); + result = value->as_xml_node()->to_value(); else throw_(calc_error, "Attempt to call text() on a non-node value"); return true; @@ -679,14 +679,14 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const #endif string ident = tok.value.as_string(); - int id = -1; if (std::isdigit(ident[0])) { node.reset(new op_t(op_t::ARG_INDEX)); node->arg_index = lexical_cast<unsigned int>(ident.c_str()); } - else if ((id = document_t::lookup_builtin_id(ident)) != -1) { + else if (optional<node_t::nameid_t> id = + document_t::lookup_builtin_id(ident)) { node.reset(new op_t(op_t::NODE_ID)); - node->name_id = id; + node->name_id = *id; } else { node.reset(new op_t(op_t::NODE_NAME)); @@ -1213,11 +1213,8 @@ void xpath_t::op_t::find_values(value_t * context, scope_t * scope, if (recursive) { if (context->type == value_t::XML_NODE) { node_t * ptr = context->as_xml_node(); - if (ptr->has_flags(XML_NODE_IS_PARENT)) { - parent_node_t * parent = static_cast<parent_node_t *>(ptr); - for (node_t * node = parent->children(); - node; - node = node->next) { + if (ptr->is_parent_node()) { + foreach (node_t * node, ptr->as_parent_node()) { value_t temp(node); find_values(&temp, scope, result_seq, recursive); } @@ -1308,8 +1305,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, case document_t::PARENT: if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing parent node from a non-node value"); - else if (context->as_xml_node()->parent) - return wrap_value(context->as_xml_node()->parent)->acquire(); + else if (context->as_xml_node()->parent()) + return wrap_value(&*context->as_xml_node()->parent())->acquire(); else throw_(compile_error, "Referencing parent node from the root node"); @@ -1317,15 +1314,14 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing root node from a non-node value"); else - return wrap_value(context->as_xml_node()->document->top)->acquire(); + return wrap_value(&context->as_xml_node()->document())->acquire(); case document_t::ALL: { if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing child nodes from a non-node value"); - parent_node_t * parent = context->as_xml_node()->as_parent_node(); value_t::sequence_t nodes; - for (node_t * node = parent->children(); node; node = node->next) + foreach (node_t * node, context->as_xml_node()->as_parent_node()) nodes.push_back(node); return wrap_value(nodes)->acquire(); @@ -1343,37 +1339,37 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, // First, look up the symbol as a node name within the current // context. If any exist, then return the set of names. - value_t::sequence_t nodes; + if (ptr->is_parent_node()) { + value_t::sequence_t nodes; - if (ptr->has_flags(XML_NODE_IS_PARENT)) { - parent_node_t * parent = static_cast<parent_node_t *>(ptr); - for (node_t * node = parent->children(); - node; - node = node->next) { + foreach (node_t * node, ptr->as_parent_node()) { if ((kind == NODE_NAME && std::strcmp(name->c_str(), node->name()) == 0) || - (kind == NODE_ID && name_id == node->name_id)) + (kind == NODE_ID && name_id == node->name_id())) nodes.push_back(node); } + return wrap_value(nodes)->acquire(); } - return wrap_value(nodes)->acquire(); } else { assert(ptr); - int id = ptr->document->lookup_name_id(*name); - if (id != -1) { + if (optional<node_t::nameid_t> id = + ptr->document().lookup_name_id(*name)) { op_t * node = new_node(NODE_ID); - node->name_id = id; + node->name_id = *id; return node->acquire(); } } } return acquire(); - case ATTR_NAME: { - // jww (2006-09-29): Attrs should map strings to values, not strings - const char * value = context->as_xml_node()->get_attr(name->c_str()); - return wrap_value(value)->acquire(); - } + case ATTR_NAME: + if (optional<node_t::nameid_t> id = + context->as_xml_node()->document().lookup_name_id(*name)) { + optional<const string&> value = context->as_xml_node()->get_attr(*id); + if (value) + return wrap_value(*value)->acquire(); + } + return acquire(); case VAR_NAME: case FUNC_NAME: @@ -1903,23 +1899,16 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, return NULL; } -void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const +void xpath_t::calc(value_t& result, node_t& node, scope_t * scope) const { #if 0 try { #endif - if (node) { - value_t context_node(node); - xpath_t final(ptr->compile(&context_node, scope, true)); - // jww (2006-09-09): Give a better error here if this is not - // actually a value - final->get_value(result); - } else { - std::auto_ptr<terminal_node_t> fake_node(new terminal_node_t(NULL)); - value_t context_node(fake_node.get()); - xpath_t final(ptr->compile(&context_node, scope, true)); - final->get_value(result); - } + value_t context_node(&node); + xpath_t final(ptr->compile(&context_node, scope, true)); + // jww (2006-09-09): Give a better error here if this is not + // actually a value + final->get_value(result); #if 0 } catch (error * err) { @@ -2041,11 +2030,7 @@ bool xpath_t::op_t::print(std::ostream& out, break; case NODE_ID: -#ifdef THREADSAFE out << '%' << name_id; -#else - out << node_t::document->lookup_name(name_id); -#endif break; case NODE_NAME: @@ -2331,11 +2316,7 @@ void xpath_t::op_t::dump(std::ostream& out, const int depth) const break; case NODE_ID: -#ifdef THREADSAFE out << "NODE_ID - " << name_id; -#else - out << "NODE_ID - " << node_t::document->lookup_name(name_id); -#endif break; case ATTR_NAME: |