2005-08-04 22:42:30 +02:00
|
|
|
#ifndef ARABICA_XPATHIC_XPATH_PARSER_HPP
|
|
|
|
#define ARABICA_XPATHIC_XPATH_PARSER_HPP
|
|
|
|
|
|
|
|
#include <boost/spirit/core.hpp>
|
|
|
|
#include <boost/spirit/tree/ast.hpp>
|
|
|
|
#include <string>
|
|
|
|
#include <stdexcept>
|
2005-08-16 22:59:04 +02:00
|
|
|
#include <map>
|
2005-08-04 22:42:30 +02:00
|
|
|
#include "xpath_object.hpp"
|
2005-08-16 22:59:04 +02:00
|
|
|
#include "xpath_expression.hpp"
|
2005-08-04 22:42:30 +02:00
|
|
|
#include "xpath_ast.hpp"
|
|
|
|
#include "xpath_grammar.hpp"
|
|
|
|
#include "xpath_namespace_context.hpp"
|
|
|
|
#include "xpath_function_resolver.hpp"
|
2005-08-16 13:40:56 +02:00
|
|
|
#include "xpath_variable_resolver.hpp"
|
2005-08-04 22:42:30 +02:00
|
|
|
#include "xpath_resolver_holder.hpp"
|
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
namespace XPath
|
|
|
|
{
|
|
|
|
|
|
|
|
class SyntaxException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SyntaxException(const std::string& thing) : std::runtime_error("Bad XPath: " + thing) { }
|
|
|
|
}; // class SyntaxException
|
|
|
|
|
|
|
|
class RuntimeException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
RuntimeException(const std::string& thing) : std::runtime_error("Cannot evaluate XPath: " + thing) { }
|
|
|
|
}; // class RuntimeException
|
|
|
|
|
|
|
|
class UnsupportedException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
UnsupportedException(const std::string& thing) : std::runtime_error("Sorry, haven't implemented '" + thing + "' yet") { }
|
|
|
|
}; // class UnsupportedException
|
|
|
|
|
2005-08-22 17:35:20 +02:00
|
|
|
namespace impl
|
|
|
|
{
|
|
|
|
template<class string_type, class string_adaptor> class CompilationContext;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-22 17:35:20 +02:00
|
|
|
template<class string_type, class string_adaptor> class StepExpression;
|
2005-08-18 22:47:01 +02:00
|
|
|
|
2005-08-22 17:35:20 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class StepList : public std::vector<impl::StepExpression<string_type, string_adaptor>*> { };
|
|
|
|
} // namespace impl
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
2005-08-04 22:42:30 +02:00
|
|
|
class XPath
|
|
|
|
{
|
|
|
|
public:
|
2005-08-16 22:59:04 +02:00
|
|
|
XPath()
|
|
|
|
{
|
|
|
|
resetNamespaceContext();
|
|
|
|
resetVariableResolver();
|
|
|
|
resetFunctionResolver();
|
|
|
|
} // XPath
|
|
|
|
|
|
|
|
~XPath()
|
|
|
|
{
|
|
|
|
} // ~XPath
|
|
|
|
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpressionPtr<string_type, string_adaptor> compile(const string_type& xpath) const
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-12-18 23:22:13 +01:00
|
|
|
return do_compile(xpath, &XPath::parse_xpath, &XPath::compile_expression);
|
2005-08-16 22:59:04 +02:00
|
|
|
} // compile
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpressionPtr<string_type, string_adaptor> compile_expr(const string_type& xpath) const
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-12-18 23:22:13 +01:00
|
|
|
return do_compile(xpath, &XPath::parse_xpath_expr, &XPath::compile_expression);
|
|
|
|
} // compile_expr
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-12-16 20:09:18 +01:00
|
|
|
XPathExpressionPtr<string_type, string_adaptor> compile_match(const string_type& xpath) const
|
|
|
|
{
|
2005-12-18 23:22:13 +01:00
|
|
|
return do_compile(xpath, &XPath::parse_xpath_match, &XPath::compile_match);
|
|
|
|
} // compile_match
|
2005-12-16 20:09:18 +01:00
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
XPathValuePtr<string_type> evaluate(const string_type& xpath, const DOM::Node<string_type>& context) const
|
|
|
|
{
|
2005-08-17 12:13:05 +02:00
|
|
|
ExecutionContext<string_type, string_adaptor> executionContext;
|
2005-08-16 22:59:04 +02:00
|
|
|
executionContext.setVariableResolver(getVariableResolver());
|
|
|
|
return compile(xpath)->evaluate(context, executionContext);
|
|
|
|
} // evaluate
|
|
|
|
|
|
|
|
XPathValuePtr<string_type> evaluate_expr(const string_type& xpath, const DOM::Node<string_type>& context) const
|
|
|
|
{
|
2005-08-17 12:13:05 +02:00
|
|
|
ExecutionContext<string_type, string_adaptor> executionContext;
|
2005-08-16 22:59:04 +02:00
|
|
|
executionContext.setVariableResolver(getVariableResolver());
|
|
|
|
return compile_expr(xpath)->evaluate(context, executionContext);
|
|
|
|
} // evaluate_expr
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-17 10:50:41 +02:00
|
|
|
void setNamespaceContext(const NamespaceContext<string_type, string_adaptor>& namespaceContext) { namespaceContext_.set(namespaceContext); }
|
|
|
|
void setNamespaceContext(NamespaceContextPtr<string_type, string_adaptor> namespaceContext) { namespaceContext_.set(namespaceContext); }
|
|
|
|
const NamespaceContext<string_type, string_adaptor>& getNamespaceContext() const { return namespaceContext_.get(); }
|
|
|
|
void resetNamespaceContext() { namespaceContext_.set(NamespaceContextPtr<string_type, string_adaptor>(new NullNamespaceContext<string_type, string_adaptor>())); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-17 11:17:18 +02:00
|
|
|
void setVariableResolver(const VariableResolver<string_type, string_adaptor>& variableResolver) { variableResolver_.set(variableResolver); }
|
|
|
|
void setVariableResolver(VariableResolverPtr<string_type, string_adaptor> variableResolver) { variableResolver_.set(variableResolver); }
|
|
|
|
const VariableResolver<string_type, string_adaptor>& getVariableResolver() const { return variableResolver_.get(); }
|
|
|
|
void resetVariableResolver() { variableResolver_.set(VariableResolverPtr<string_type, string_adaptor>(new NullVariableResolver<string_type, string_adaptor>())); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-17 11:10:38 +02:00
|
|
|
void setFunctionResolver(const FunctionResolver<string_type, string_adaptor>& functionResolver) { functionResolver_.set(functionResolver); }
|
|
|
|
void setFunctionResolver(FunctionResolverPtr<string_type, string_adaptor> functionResolver) { functionResolver_.set(functionResolver); }
|
|
|
|
const FunctionResolver<string_type, string_adaptor>& getFunctionResolver() const { return functionResolver_.get(); }
|
|
|
|
void resetFunctionResolver() { functionResolver_.set(FunctionResolverPtr<string_type, string_adaptor>(new NullFunctionResolver<string_type, string_adaptor>())); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
private:
|
2005-12-18 23:22:13 +01:00
|
|
|
typedef typename impl::types<string_adaptor>::tree_info_t(XPath::*parserFn)(const string_type& str) const;
|
|
|
|
typedef XPathExpression<string_type, string_adaptor>* (*compilerFn)(typename impl::types<string_adaptor>::node_iter_t const& i,
|
|
|
|
impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpressionPtr<string_type, string_adaptor> do_compile(const string_type& xpath,
|
2005-12-18 23:22:13 +01:00
|
|
|
parserFn parser,
|
|
|
|
compilerFn compiler) const
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::tree_info_t ast;
|
2005-08-16 22:59:04 +02:00
|
|
|
try {
|
2005-12-18 23:22:13 +01:00
|
|
|
ast = (this->*parser)(xpath);
|
2005-08-16 22:59:04 +02:00
|
|
|
if(!ast.full)
|
2005-12-16 20:09:18 +01:00
|
|
|
throw SyntaxException(string_adaptor::asStdString(xpath));
|
2005-08-16 22:59:04 +02:00
|
|
|
|
2005-08-22 17:35:20 +02:00
|
|
|
impl::CompilationContext<string_type, string_adaptor> context(*this, getNamespaceContext(), getFunctionResolver());
|
2005-12-18 23:22:13 +01:00
|
|
|
return XPathExpressionPtr<string_type, string_adaptor>(compiler(ast.trees.begin(), context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // try
|
2005-12-16 20:09:18 +01:00
|
|
|
catch(const std::exception&)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-12-16 20:09:18 +01:00
|
|
|
throw;
|
2005-08-16 22:59:04 +02:00
|
|
|
} // catch
|
|
|
|
catch(...)
|
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
throw SyntaxException(string_adaptor().asStdString(xpath));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // catch
|
|
|
|
} // do_compile
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::tree_info_t parse_xpath(const string_type& str) const
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::str_iter_t first = string_adaptor::begin(str), last = string_adaptor::end(str);
|
2005-08-16 22:59:04 +02:00
|
|
|
return ast_parse(first, last, xpathg_);
|
|
|
|
} // parse_xpath
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::tree_info_t parse_xpath_expr(const string_type& str) const
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::str_iter_t first = string_adaptor::begin(str), last = string_adaptor::end(str);
|
2005-08-16 22:59:04 +02:00
|
|
|
return ast_parse(first, last, xpathge_);
|
2005-12-15 23:11:16 +01:00
|
|
|
} // parse_xpath_expr
|
|
|
|
|
|
|
|
typename impl::types<string_adaptor>::tree_info_t parse_xpath_match(const string_type& str) const
|
|
|
|
{
|
|
|
|
typename impl::types<string_adaptor>::str_iter_t first = string_adaptor::begin(str), last = string_adaptor::end(str);
|
|
|
|
return ast_parse(first, last, xpathgm_);
|
|
|
|
} // parse_xpath_match
|
|
|
|
|
2005-08-22 17:59:57 +02:00
|
|
|
impl::xpath_grammar xpathg_;
|
|
|
|
impl::xpath_grammar_expr xpathge_;
|
2005-12-15 23:11:16 +01:00
|
|
|
impl::xpath_grammar_match xpathgm_;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-22 17:35:20 +02:00
|
|
|
impl::ResolverHolder<const NamespaceContext<string_type, string_adaptor> > namespaceContext_;
|
|
|
|
impl::ResolverHolder<const VariableResolver<string_type, string_adaptor> > variableResolver_;
|
|
|
|
impl::ResolverHolder<const FunctionResolver<string_type, string_adaptor> > functionResolver_;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
public:
|
2005-09-25 22:09:49 +02:00
|
|
|
static XPathExpression<string_type, string_adaptor>* compile_expression(typename impl::types<string_adaptor>::node_iter_t const& i,
|
2005-08-22 17:35:20 +02:00
|
|
|
impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
long id = impl::getNodeId<string_adaptor>(i);
|
2005-08-16 22:59:04 +02:00
|
|
|
|
2005-12-18 23:22:13 +01:00
|
|
|
if(XPath::expression_factory().find(id) == XPath::expression_factory().end())
|
|
|
|
throw UnsupportedException(string_adaptor().asStdString(XPath::names()[id]));
|
|
|
|
|
|
|
|
return XPath::expression_factory()[id](i, context);
|
|
|
|
} // compile_expression
|
|
|
|
|
|
|
|
static XPathExpression<string_type, string_adaptor>* compile_match(typename impl::types<string_adaptor>::node_iter_t const& i,
|
|
|
|
impl::CompilationContext<string_type, string_adaptor>& context)
|
|
|
|
{
|
|
|
|
long id = impl::getNodeId<string_adaptor>(i);
|
|
|
|
|
|
|
|
if(XPath::match_factory().find(id) == XPath::match_factory().end())
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-12-18 23:22:13 +01:00
|
|
|
XPath::dump(i, 0);
|
2005-09-25 22:09:49 +02:00
|
|
|
throw UnsupportedException(string_adaptor().asStdString(XPath::names()[id]));
|
2005-08-16 22:59:04 +02:00
|
|
|
}
|
|
|
|
|
2005-12-18 23:22:13 +01:00
|
|
|
return XPath::match_factory()[id](i, context);
|
|
|
|
} // compile_match
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
private:
|
2005-09-25 22:09:49 +02:00
|
|
|
static XPathExpression<string_type, string_adaptor>* createAbsoluteLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createRelativeLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createSingleStepRelativeLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createFunction(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createBinaryExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createLiteral(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createNumber(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createVariable(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createSingleStepAbsoluteLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createUnaryExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createUnaryNegativeExpr(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
|
|
|
|
static impl::StepList<string_type, string_adaptor> createStepList(typename impl::types<string_adaptor>::node_iter_t const& from, typename impl::types<string_adaptor>::node_iter_t const& to, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
|
2005-12-18 23:22:13 +01:00
|
|
|
static XPathExpression<string_type, string_adaptor>* createDocMatch(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createSingleMatchStep(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
static XPathExpression<string_type, string_adaptor>* createStepPattern(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
typedef XPathExpression<string_type, string_adaptor>* (*compileFn)(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context);
|
2005-12-18 23:22:13 +01:00
|
|
|
|
|
|
|
static std::map<int, compileFn>& expression_factory()
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
|
|
|
static std::map<int, compileFn> f = init_createFunctions();
|
|
|
|
return f;
|
2005-12-18 23:22:13 +01:00
|
|
|
} // expression_factory
|
|
|
|
|
|
|
|
static std::map<int, compileFn>& match_factory()
|
|
|
|
{
|
|
|
|
static std::map<int, compileFn> f = init_matchCreateFunctions();
|
|
|
|
return f;
|
|
|
|
} // match_factory
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
static std::map<int, string_type>& names()
|
|
|
|
{
|
|
|
|
static std::map<int, string_type> n = init_debugNames();
|
|
|
|
return n;
|
|
|
|
} // names
|
|
|
|
|
|
|
|
static const std::map<int, compileFn> init_createFunctions()
|
|
|
|
{
|
2005-08-21 14:48:00 +02:00
|
|
|
std::map<int, compileFn> factory;
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
factory[impl::AbsoluteLocationPath_id] = createAbsoluteLocationPath;
|
|
|
|
factory[impl::RelativeLocationPath_id] = createRelativeLocationPath;
|
|
|
|
factory[impl::AbbreviatedAbsoluteLocationPath_id] = createAbsoluteLocationPath;
|
|
|
|
factory[impl::Step_id] = createRelativeLocationPath;
|
|
|
|
factory[impl::PathExpr_id] = createRelativeLocationPath;
|
|
|
|
factory[impl::FilterExpr_id] = createRelativeLocationPath;
|
|
|
|
|
|
|
|
factory[impl::PrimaryExpr_id] = createExpression;
|
|
|
|
|
|
|
|
factory[impl::FunctionCall_id] = createFunction;
|
|
|
|
|
|
|
|
factory[impl::AdditiveExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::MultiplicativeExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::EqualityExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::RelationalExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::OrExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::AndExpr_id] = createBinaryExpression;
|
|
|
|
factory[impl::UnionExpr_id] = createBinaryExpression;
|
|
|
|
|
|
|
|
factory[impl::Literal_id] = createLiteral;
|
|
|
|
factory[impl::Number_id] = createNumber;
|
|
|
|
factory[impl::Digits_id] = createNumber;
|
|
|
|
|
|
|
|
factory[impl::VariableReference_id] = createVariable;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
factory[impl::NodeTest_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::QName_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::NCName_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::AnyName_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::Text_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::Comment_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::ProcessingInstruction_id] = createSingleStepRelativeLocationPath;
|
2005-12-16 11:17:39 +01:00
|
|
|
factory[impl::Node_id] = createSingleStepRelativeLocationPath;
|
2005-08-16 22:59:04 +02:00
|
|
|
factory[impl::Slash_id] = createSingleStepAbsoluteLocationPath;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
factory[impl::SelfSelect_id] = createSingleStepRelativeLocationPath;
|
|
|
|
factory[impl::ParentSelect_id] = createSingleStepRelativeLocationPath;
|
|
|
|
|
|
|
|
factory[impl::UnaryExpr_id] = createUnaryExpression;
|
|
|
|
factory[impl::UnaryMinusOperator_id] = createUnaryNegativeExpr;
|
|
|
|
|
|
|
|
return factory;
|
|
|
|
} // init_createFunctions
|
|
|
|
|
2005-12-18 23:22:13 +01:00
|
|
|
static const std::map<int, compileFn> init_matchCreateFunctions()
|
|
|
|
{
|
|
|
|
std::map<int, compileFn> factory;
|
|
|
|
|
|
|
|
factory[impl::Slash_id] = createDocMatch;
|
|
|
|
factory[impl::NCName_id] = createSingleMatchStep;
|
|
|
|
factory[impl::StepPattern_id] = createStepPattern;
|
|
|
|
|
|
|
|
return factory;
|
|
|
|
} // init_matchCreateFunctions
|
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
static const std::map<int, string_type> init_debugNames()
|
|
|
|
{
|
2005-08-19 19:20:06 +02:00
|
|
|
std::map<int, string_type> names;
|
2005-09-30 23:36:11 +02:00
|
|
|
typedef string_adaptor SA;
|
|
|
|
|
|
|
|
names[impl::LocationPath_id] = SA::construct_from_utf8("LocationPath");
|
|
|
|
names[impl::AbsoluteLocationPath_id] = SA::construct_from_utf8("AbsoluteLocationPath");
|
|
|
|
names[impl::RelativeLocationPath_id] = SA::construct_from_utf8("RelativeLocationPath");
|
|
|
|
names[impl::Step_id] = SA::construct_from_utf8("Step");
|
|
|
|
names[impl::AxisSpecifier_id] = SA::construct_from_utf8("AxisSpecifier");
|
|
|
|
names[impl::NodeTest_id] = SA::construct_from_utf8("NodeTest");
|
|
|
|
names[impl::Predicate_id] = SA::construct_from_utf8("Predicate");
|
|
|
|
names[impl::PredicateExpr_id] = SA::construct_from_utf8("PredicateExpr");
|
|
|
|
names[impl::AbbreviatedAbsoluteLocationPath_id] = SA::construct_from_utf8("AbbreviatedAbsoluteLocationPath");
|
|
|
|
names[impl::AbbreviatedStep_id] = SA::construct_from_utf8("AbbreviatedStep");
|
|
|
|
names[impl::AbbreviatedAxisSpecifier_id] = SA::construct_from_utf8("AbbreviatedAxisSpecifier");
|
|
|
|
names[impl::Expr_id] = SA::construct_from_utf8("Expr");
|
|
|
|
names[impl::PrimaryExpr_id] = SA::construct_from_utf8("PrimaryExpr");
|
|
|
|
names[impl::FunctionCall_id] = SA::construct_from_utf8("FunctionCall");
|
|
|
|
names[impl::Argument_id] = SA::construct_from_utf8("Argument");
|
|
|
|
names[impl::UnionExpr_id] = SA::construct_from_utf8("UnionExpr");
|
|
|
|
names[impl::PathExpr_id] = SA::construct_from_utf8("PathExpr");
|
|
|
|
names[impl::FilterExpr_id] = SA::construct_from_utf8("FilterExpr");
|
|
|
|
names[impl::OrExpr_id] = SA::construct_from_utf8("OrExpr");
|
|
|
|
names[impl::AndExpr_id] = SA::construct_from_utf8("AndExpr");
|
|
|
|
names[impl::EqualityExpr_id] = SA::construct_from_utf8("EqualityExpr");
|
|
|
|
names[impl::RelationalExpr_id] = SA::construct_from_utf8("RelationalExpr");
|
|
|
|
names[impl::AdditiveExpr_id] = SA::construct_from_utf8("AdditiveExpr");
|
|
|
|
names[impl::MultiplicativeExpr_id] = SA::construct_from_utf8("MultiplicativeExpr");
|
|
|
|
names[impl::UnaryExpr_id] = SA::construct_from_utf8("UnaryExpr");
|
|
|
|
names[impl::Literal_id] = SA::construct_from_utf8("Literal");
|
|
|
|
names[impl::Number_id] = SA::construct_from_utf8("Number");
|
|
|
|
names[impl::Digits_id] = SA::construct_from_utf8("Digits");
|
|
|
|
names[impl::MultiplyOperator_id] = SA::construct_from_utf8("MultiplyOperator");
|
|
|
|
names[impl::FunctionName_id] = SA::construct_from_utf8("FunctionName");
|
|
|
|
names[impl::VariableReference_id] = SA::construct_from_utf8("VariableReference");
|
|
|
|
names[impl::NameTest_id] = SA::construct_from_utf8("NameTest");
|
|
|
|
names[impl::S_id] = SA::construct_from_utf8("S");
|
|
|
|
names[impl::NodeType_id] = SA::construct_from_utf8("NodeType");
|
|
|
|
names[impl::AxisName_id] = SA::construct_from_utf8("AxisName");
|
|
|
|
|
|
|
|
names[impl::QName_id] = SA::construct_from_utf8("QName");
|
|
|
|
names[impl::Prefix_id] = SA::construct_from_utf8("Prefix");
|
|
|
|
names[impl::LocalPart_id] = SA::construct_from_utf8("LocalPart");
|
|
|
|
names[impl::NCName_id] = SA::construct_from_utf8("NCName");
|
|
|
|
names[impl::NCNameChar_id] = SA::construct_from_utf8("NCNameChar");
|
|
|
|
|
|
|
|
names[impl::Slash_id] = SA::construct_from_utf8("/");
|
|
|
|
names[impl::SlashSlash_id] = SA::construct_from_utf8("//");
|
|
|
|
|
|
|
|
names[impl::AncestorOrSelf_id] = SA::construct_from_utf8("ancestor-or-self::");
|
|
|
|
names[impl::Ancestor_id] = SA::construct_from_utf8("ancestor::");
|
|
|
|
names[impl::Attribute_id] = SA::construct_from_utf8("attribute::");
|
|
|
|
names[impl::Child_id] = SA::construct_from_utf8("child::");
|
|
|
|
names[impl::DescendantOrSelf_id] = SA::construct_from_utf8("descendant-or-self::");
|
|
|
|
names[impl::Descendant_id] = SA::construct_from_utf8("descendant::");
|
|
|
|
names[impl::FollowingSibling_id] = SA::construct_from_utf8("following-sibling::");
|
|
|
|
names[impl::Following_id] = SA::construct_from_utf8("following::");
|
|
|
|
names[impl::Namespace_id] = SA::construct_from_utf8("namespace::");
|
|
|
|
names[impl::Parent_id] = SA::construct_from_utf8("parent::");
|
|
|
|
names[impl::PrecedingSibling_id] = SA::construct_from_utf8("preceding-sibling::");
|
|
|
|
names[impl::Preceding_id] = SA::construct_from_utf8("preceding::");
|
|
|
|
names[impl::Self_id] = SA::construct_from_utf8("self::");
|
|
|
|
|
|
|
|
names[impl::Comment_id] = SA::construct_from_utf8("comment()");
|
|
|
|
names[impl::Text_id] = SA::construct_from_utf8("text()");
|
|
|
|
names[impl::ProcessingInstruction_id] = SA::construct_from_utf8("processing-instruction()");
|
|
|
|
names[impl::Node_id] = SA::construct_from_utf8("node()");
|
|
|
|
names[impl::AnyName_id] = SA::construct_from_utf8("AnyName");
|
|
|
|
|
|
|
|
names[impl::SelfSelect_id] = SA::construct_from_utf8("SelfSelect");
|
|
|
|
names[impl::ParentSelect_id] = SA::construct_from_utf8("ParentSelect");
|
|
|
|
|
|
|
|
names[impl::LeftSquare_id] = SA::construct_from_utf8("[");
|
|
|
|
names[impl::RightSquare_id] = SA::construct_from_utf8("]");
|
|
|
|
|
|
|
|
names[impl::LeftBracket_id] = SA::construct_from_utf8("(");
|
|
|
|
names[impl::RightBracket_id] = SA::construct_from_utf8(")");
|
|
|
|
|
|
|
|
names[impl::PlusOperator_id] = SA::construct_from_utf8("+");
|
|
|
|
names[impl::MinusOperator_id] = SA::construct_from_utf8("-");
|
|
|
|
names[impl::ModOperator_id] = SA::construct_from_utf8("mod");
|
|
|
|
names[impl::DivOperator_id] = SA::construct_from_utf8("div");
|
|
|
|
names[impl::EqualsOperator_id] = SA::construct_from_utf8("=");
|
|
|
|
names[impl::NotEqualsOperator_id] = SA::construct_from_utf8("!=");
|
|
|
|
names[impl::LessThanOperator_id] = SA::construct_from_utf8("<");
|
|
|
|
names[impl::LessThanEqualsOperator_id] = SA::construct_from_utf8("<=");
|
|
|
|
names[impl::GreaterThanOperator_id] = SA::construct_from_utf8(">");
|
|
|
|
names[impl::GreaterThanEqualsOperator_id] = SA::construct_from_utf8(">=");
|
|
|
|
|
|
|
|
names[impl::OrOperator_id] = SA::construct_from_utf8("or");
|
|
|
|
names[impl::AndOperator_id] = SA::construct_from_utf8("and");
|
|
|
|
names[impl::UnionOperator_id] = SA::construct_from_utf8("union");
|
|
|
|
names[impl::UnaryMinusOperator_id] = SA::construct_from_utf8("minus");
|
2005-08-16 22:59:04 +02:00
|
|
|
|
2005-12-15 23:11:16 +01:00
|
|
|
names[impl::Pattern_id] = SA::construct_from_utf8("Pattern");
|
|
|
|
names[impl::LocationPathPattern_id] = SA::construct_from_utf8("LocationPathPattern");
|
|
|
|
names[impl::IdKeyPattern_id] = SA::construct_from_utf8("IdKeyPattern");
|
|
|
|
names[impl::RelativePathPattern_id] = SA::construct_from_utf8("RelativePathPattern");
|
|
|
|
names[impl::StepPattern_id] = SA::construct_from_utf8("StepPattern");
|
|
|
|
names[impl::ChildOrAttributeAxisSpecifier_id] = SA::construct_from_utf8("ChildOrAttributeAxisSpecifier");
|
|
|
|
|
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
return names;
|
|
|
|
} // init_debugNames
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
static void dump(typename impl::types<string_adaptor>::node_iter_t const& i, int depth)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
|
|
|
long id = static_cast<long>(i->value.id().to_long());
|
|
|
|
|
|
|
|
for(int d = 0; d < depth; ++d)
|
|
|
|
std::cerr << ' ';
|
|
|
|
std::cerr << names()[id] << " - " << std::string(i->value.begin(), i->value.end()) << std::endl;
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
for(typename impl::types<string_adaptor>::node_iter_t c = i->children.begin(); c != i->children.end(); ++c)
|
2005-08-16 22:59:04 +02:00
|
|
|
dump(c, depth+2);
|
|
|
|
} // dump
|
2005-12-16 20:09:18 +01:00
|
|
|
|
2005-08-04 22:42:30 +02:00
|
|
|
XPath(const XPath&);
|
|
|
|
XPath& operator=(const XPath&);
|
|
|
|
bool operator==(const XPath&) const;
|
|
|
|
}; // class XPath
|
|
|
|
|
|
|
|
} // namespace XPath
|
|
|
|
|
|
|
|
} // namespace Arabica
|
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
#include "xpath_value.hpp"
|
|
|
|
#include "xpath_arithmetic.hpp"
|
|
|
|
#include "xpath_relational.hpp"
|
|
|
|
#include "xpath_logical.hpp"
|
|
|
|
#include "xpath_step.hpp"
|
|
|
|
#include "xpath_compile_context.hpp"
|
|
|
|
#include "xpath_variable.hpp"
|
|
|
|
#include "xpath_function_holder.hpp"
|
|
|
|
#include "xpath_union.hpp"
|
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace XPath
|
|
|
|
{
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createAbsoluteLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-08-22 17:35:20 +02:00
|
|
|
return new impl::AbsoluteLocationPath<string_type, string_adaptor>(createStepList(i->children.begin(), i->children.end(), context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createAbsoluteLocationPath
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createRelativeLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-08-22 17:35:20 +02:00
|
|
|
return new impl::RelativeLocationPath<string_type, string_adaptor>(createStepList(i->children.begin(), i->children.end(), context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createRelativeLocationPath
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createSingleStepRelativeLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t n = i;
|
2005-08-22 17:35:20 +02:00
|
|
|
return new impl::RelativeLocationPath<string_type, string_adaptor>(impl::StepFactory<string_type, string_adaptor>::createStep(n, context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createSingleStepRelativeLocationPath
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t c = i->children.begin();
|
|
|
|
impl::skipWhitespace<string_adaptor>(c);
|
2005-08-16 22:59:04 +02:00
|
|
|
return XPath<string_type, string_adaptor>::compile_expression(c, context);
|
|
|
|
} // createExpression
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createFunction(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t c = i->children.begin();
|
2005-09-30 23:36:11 +02:00
|
|
|
string_type name = string_adaptor::construct(c->value.begin(), c->value.end());
|
2005-08-16 22:59:04 +02:00
|
|
|
++c;
|
2005-09-25 22:09:49 +02:00
|
|
|
impl::skipWhitespace<string_adaptor>(c);
|
|
|
|
assert(impl::getNodeId<string_adaptor>(c) == impl::LeftBracket_id);
|
2005-08-16 22:59:04 +02:00
|
|
|
++c;
|
2005-09-25 22:09:49 +02:00
|
|
|
impl::skipWhitespace<string_adaptor>(c);
|
2005-08-16 22:59:04 +02:00
|
|
|
|
2005-08-17 12:13:05 +02:00
|
|
|
std::vector<XPathExpressionPtr<string_type, string_adaptor> > args;
|
2005-09-25 22:09:49 +02:00
|
|
|
while(impl::getNodeId<string_adaptor>(c) != impl::RightBracket_id)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpressionPtr<string_type, string_adaptor> arg(XPath<string_type, string_adaptor>::compile_expression(c++, context));
|
2005-08-16 22:59:04 +02:00
|
|
|
args.push_back(arg);
|
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
impl::skipWhitespace<string_adaptor>(c);
|
2005-08-16 22:59:04 +02:00
|
|
|
} // while ...
|
|
|
|
// maybe trailing whitespace ...
|
|
|
|
|
2005-08-22 17:04:27 +02:00
|
|
|
return impl::FunctionHolder<string_type, string_adaptor>::createFunction(name, args, context);
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createFunction
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createBinaryExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t c = i->children.begin();
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* p1 = XPath<string_type, string_adaptor>::compile_expression(c, context);
|
2005-08-16 22:59:04 +02:00
|
|
|
++c;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
long op = impl::getNodeId<string_adaptor>(c);
|
2005-08-16 22:59:04 +02:00
|
|
|
++c;
|
2005-08-17 12:13:05 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* p2 = XPath<string_type, string_adaptor>::compile_expression(c, context);
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
switch(op)
|
|
|
|
{
|
|
|
|
case impl::PlusOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::PlusOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::MinusOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::MinusOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::MultiplyOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::MultiplyOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::DivOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::DivideOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::ModOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::ModOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::EqualsOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::EqualsOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::NotEqualsOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::NotEqualsOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::LessThanOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::LessThanOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::LessThanEqualsOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::LessThanEqualsOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::GreaterThanOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::GreaterThanOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::GreaterThanEqualsOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::GreaterThanEqualsOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::OrOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::OrOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::AndOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::AndOperator<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
case impl::UnionOperator_id:
|
2005-08-22 17:04:27 +02:00
|
|
|
p1 = new impl::UnionExpression<string_type, string_adaptor>(p1, p2);
|
2005-08-16 22:59:04 +02:00
|
|
|
break;
|
|
|
|
default:
|
2005-09-25 22:09:49 +02:00
|
|
|
throw UnsupportedException(boost::lexical_cast<std::string>(op));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // switch
|
|
|
|
}
|
|
|
|
while(++c != i->children.end());
|
|
|
|
|
|
|
|
return p1;
|
|
|
|
} // createBinaryExpression
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createLiteral(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
string_type str = string_adaptor::construct(i->value.begin(), i->value.end());
|
2005-08-17 10:25:24 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(str);
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createLiteral
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createNumber(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
string_type str = string_adaptor::construct(i->value.begin(), i->value.end());
|
2005-09-25 22:09:49 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(boost::lexical_cast<double>(str));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createNumber
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createVariable(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
string_type str = string_adaptor::construct(i->value.begin()+1, i->value.end());
|
2005-09-25 22:09:49 +02:00
|
|
|
return new Variable<string_type, string_adaptor>(str);
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createVariable
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createSingleStepAbsoluteLocationPath(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t n = i;
|
2005-08-22 17:35:20 +02:00
|
|
|
return new impl::AbsoluteLocationPath<string_type, string_adaptor>(impl::StepFactory<string_type, string_adaptor>::createStep(n, context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createSingleStepAbsoluteLocationPath
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createUnaryExpression(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
|
|
|
return XPath<string_type, string_adaptor>::compile_expression(i->children.begin(), context);
|
|
|
|
} // createUnaryExpression
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createUnaryNegativeExpr(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-08-22 17:04:27 +02:00
|
|
|
return new impl::UnaryNegative<string_type, string_adaptor>(XPath<string_type, string_adaptor>::compile_expression(i+1, context));
|
2005-08-16 22:59:04 +02:00
|
|
|
} // createUnaryNegativeExpr
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
2005-09-25 22:09:49 +02:00
|
|
|
impl::StepList<string_type, string_adaptor> XPath<string_type, string_adaptor>::createStepList(typename impl::types<string_adaptor>::node_iter_t const& from,
|
|
|
|
typename impl::types<string_adaptor>::node_iter_t const& to,
|
2005-08-22 17:35:20 +02:00
|
|
|
impl::CompilationContext<string_type, string_adaptor>& context)
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
2005-08-22 17:35:20 +02:00
|
|
|
impl::StepList<string_type, string_adaptor> steps;
|
2005-08-16 22:59:04 +02:00
|
|
|
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t c = from;
|
|
|
|
typename impl::types<string_adaptor>::node_iter_t end = to;
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
while(c != end)
|
2005-09-25 22:09:49 +02:00
|
|
|
switch(impl::getNodeId<string_adaptor>(c))
|
2005-08-16 22:59:04 +02:00
|
|
|
{
|
|
|
|
case impl::S_id:
|
|
|
|
case impl::Slash_id:
|
|
|
|
++c; // just drop it
|
|
|
|
break;
|
|
|
|
case impl::RelativeLocationPath_id:
|
|
|
|
// might get here when handling an absolute path
|
|
|
|
end = c->children.end();
|
|
|
|
c = c->children.begin();
|
|
|
|
break;
|
|
|
|
case impl::Step_id:
|
|
|
|
{
|
2005-09-25 22:09:49 +02:00
|
|
|
typename impl::types<string_adaptor>::node_iter_t step = c->children.begin();
|
2005-08-22 17:35:20 +02:00
|
|
|
steps.push_back(impl::StepFactory<string_type, string_adaptor>::createStep(step, c->children.end(), context));
|
2005-08-16 22:59:04 +02:00
|
|
|
++c;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2005-08-22 17:35:20 +02:00
|
|
|
steps.push_back(impl::StepFactory<string_type, string_adaptor>::createStep(c, end, context));
|
2005-08-22 17:59:57 +02:00
|
|
|
} // switch(impl::getNodeId(c))
|
2005-08-16 22:59:04 +02:00
|
|
|
|
|
|
|
return steps;
|
|
|
|
} // createStepList
|
|
|
|
|
2005-12-18 23:22:13 +01:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createDocMatch(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
|
|
|
{
|
|
|
|
typename impl::types<string_adaptor>::node_iter_t n = i;
|
|
|
|
return new impl::RelativeLocationPath<string_type, string_adaptor>(impl::StepFactory<string_type, string_adaptor>::createStep(n, context));
|
|
|
|
} // createDocMatch
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createSingleMatchStep(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
|
|
|
{
|
|
|
|
typename impl::types<string_adaptor>::node_iter_t n = i;
|
|
|
|
return new impl::RelativeLocationPath<string_type, string_adaptor>(impl::StepFactory<string_type, string_adaptor>::createStep(n, i->children.end(), context, SELF));
|
|
|
|
} // createSingleMatchStep
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
XPathExpression<string_type, string_adaptor>* XPath<string_type, string_adaptor>::createStepPattern(typename impl::types<string_adaptor>::node_iter_t const& i, impl::CompilationContext<string_type, string_adaptor>& context)
|
|
|
|
{
|
|
|
|
typename impl::types<string_adaptor>::node_iter_t n = i->children.begin();
|
|
|
|
Axis axis = impl::StepFactory<string_type, string_adaptor>::getAxis(n);
|
|
|
|
if(axis == CHILD)
|
|
|
|
axis = SELF;
|
|
|
|
return new impl::RelativeLocationPath<string_type, string_adaptor>(impl::StepFactory<string_type, string_adaptor>::createStep(n, i->children.end(), context, SELF));
|
|
|
|
} // createStepPattern
|
|
|
|
|
2005-08-16 22:59:04 +02:00
|
|
|
} // namespace XPath
|
|
|
|
} // namespace Arabica
|
|
|
|
|
2005-08-04 22:42:30 +02:00
|
|
|
#endif
|