From 4ab1551932fb92e040a5451d3b67534774f992d5 Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Sun, 8 Nov 2009 09:33:56 +0000 Subject: XPath: Minor refactoring, fixed text()/etc. parsing bug (issue 33) git-svn-id: http://pugixml.googlecode.com/svn/trunk@211 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixpath.cpp | 66 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index d42c9e2..8e53487 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -1226,6 +1226,7 @@ namespace pugi enum nodetest_t { + nodetest_none, nodetest_name, nodetest_type_node, nodetest_type_comment, @@ -1550,6 +1551,9 @@ namespace pugi n.name()[strlen(m_contents)] == ':') ns.push_back(n); break; + + default: + assert(!"Unknown axis"); } } @@ -2999,7 +3003,39 @@ namespace pugi specified = false; return axis_child; } - + + nodetest_t parse_node_test_type(const char* name) + { + switch (name[0]) + { + case 'c': + if (!strcmp(name, "comment")) + return nodetest_type_comment; + + break; + + case 'n': + if (!strcmp(name, "node")) + return nodetest_type_node; + + break; + + case 'p': + if (!strcmp(name, "processing-instruction")) + return nodetest_type_pi; + + break; + + case 't': + if (!strcmp(name, "text")) + return nodetest_type_text; + + break; + } + + return nodetest_none; + } + // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall xpath_ast_node* parse_primary_expression() { @@ -3167,13 +3203,11 @@ namespace pugi return new (m_alloc.node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0, m_alloc); } - nodetest_t nt_type; + nodetest_t nt_type = nodetest_none; std::string nt_name; if (m_lexer.current() == lex_string) { - bool nodetest_specified = false; - // node name test nt_name = m_lexer.contents(); m_lexer.next(); @@ -3195,8 +3229,6 @@ namespace pugi { nt_type = nodetest_all; m_lexer.next(); - - nodetest_specified = true; } else if (m_lexer.current() == lex_string) { @@ -3206,7 +3238,7 @@ namespace pugi else throw xpath_exception("Unrecognized node test"); } - if (!nodetest_specified) + if (nt_type == nodetest_none) { // node type test or processing-instruction if (m_lexer.current() == lex_open_brace) @@ -3216,19 +3248,12 @@ namespace pugi if (m_lexer.current() == lex_close_brace) { m_lexer.next(); + + nt_type = parse_node_test_type(nt_name.c_str()); + + if (nt_type == nodetest_none) throw xpath_exception("Unrecognized node type"); - if (nt_name == "node") - nt_type = nodetest_type_node; - else if (nt_name == "text") - nt_type = nodetest_type_text; - else if (nt_name == "comment") - nt_type = nodetest_type_comment; - else if (nt_name == "processing-instruction") - nt_type = nodetest_type_pi; - else - throw xpath_exception("Unrecognized node type"); - - nt_name.erase(nt_name.begin(), nt_name.end()); + nt_name = ""; } else if (nt_name == "processing-instruction") { @@ -3378,6 +3403,9 @@ namespace pugi while (*state && *state <= 32) ++state; if (*state != '(') return parse_location_path(); + + // This looks like a function call; however this still can be a node-test. Check it. + if (parse_node_test_type(m_lexer.contents()) != nodetest_none) return parse_location_path(); } xpath_ast_node* n = parse_filter_expression(); -- cgit v1.2.3