started work on xsl:key/key()

This commit is contained in:
jez 2009-02-16 22:10:00 +00:00
parent 3e3447dcff
commit 4d9c2a485a
4 changed files with 128 additions and 1 deletions

View file

@ -0,0 +1,66 @@
#ifndef ARABICA_XSLT_KEY_HANDLER_HPP
#define ARABICA_XSLT_KEY_HANDLER_HPP
#include "../xslt_key.hpp"
#include <XML/XMLCharacterClasses.hpp>
namespace Arabica
{
namespace XSLT
{
class KeyHandler : public SAX::DefaultHandler<std::string>
{
public:
KeyHandler(CompilationContext& context) :
context_(context),
key_(0)
{
} // KeyHandler
virtual void startElement(const std::string& namespaceURI,
const std::string& localName,
const std::string& qName,
const SAX::Attributes<std::string>& atts)
{
if(key_ != 0)
throw SAX::SAXException(qName + " can not contain elements");
static const ValueRule rules[] = { { "name", true, 0 },
{ "match", true, 0 },
{ "use", true, 0 },
{ 0, false, 0 } };
std::map<std::string, std::string> attrs = gatherAttributes(qName, atts, rules);
name_ = context_.processInternalQName(attrs["name"]);
Key::MatchExprList matches = context_.xpath_match(attrs["match"]);
Arabica::XPath::XPathExpression<std::string> use = context_.xpath_expression(attrs["use"]);
key_ = new Key(matches, use);
} // startElement
virtual void endElement(const std::string& namespaceURI,
const std::string& localName,
const std::string& qName)
{
context_.stylesheet().add_key(name_, key_);
context_.pop();
} // endElement
virtual void characters(const std::string& ch)
{
for(std::string::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
if(!Arabica::XML::is_space(*i))
throw SAX::SAXException("xsl:key element must be empty");
} // characters
private:
CompilationContext& context_;
std::pair<std::string, std::string> name_;
Key* key_;
}; // class KeyHandler
} // namespace XSLT
} // namespace Arabica
#endif

View file

@ -8,6 +8,7 @@
#include "xslt_execution_context.hpp"
#include "xslt_template.hpp"
#include "xslt_top_level_param.hpp"
#include "xslt_key.hpp"
#include "xslt_stylesheet.hpp"
namespace Arabica
@ -121,6 +122,12 @@ public:
topLevelVars_.push_back(item);
} // add_item
void add_key(const std::pair<std::string, std::string>& name,
Key* key)
{
std::cerr << "Added key " << name.second << std::endl;
} // add_key
void output_settings(const Output::Settings& settings)
{
output_settings_ = settings;

View file

@ -0,0 +1,53 @@
#ifndef ARABICA_XSLT_KEY_HPP
#define ARABICA_XSLT_KEY_HPP
namespace Arabica
{
namespace XSLT
{
class Key
{
public:
typedef std::vector<Arabica::XPath::MatchExpr<std::string> > MatchExprList;
Key(MatchExprList& matches,
Arabica::XPath::XPathExpression<std::string>& use) :
matches_(matches),
use_(use),
populated_(false)
{
} // Key
Arabica::DOM::Node<std::string> lookup(const std::string& value) const
{
if(!populated_)
populate();
NodeMap::const_iterator f = nodes_.find(value);
if(f == nodes_.end())
return DOM::Node<std::string>(0);
return f->second;
} // lookup
private:
void populate() const
{
std::cerr << "Populating key map " << std::endl;
populated_ = true;
} // populate
MatchExprList matches_;
Arabica::XPath::XPathExpression<std::string> use_;
mutable bool populated_;
typedef std::map<std::string, Arabica::DOM::Node<std::string> > NodeMap;
NodeMap nodes_;
}; // class Key
} // namespace XSLT
} // namespace Arabica
#endif

View file

@ -12,6 +12,7 @@
#include "handler/xslt_include_handler.hpp"
#include "handler/xslt_output_handler.hpp"
#include "handler/xslt_namespace_alias_handler.hpp"
#include "handler/xslt_key_handler.hpp"
namespace Arabica
{
@ -143,7 +144,7 @@ const ChildElement StylesheetHandler::allowedChildren[] =
{ "decimal-format", CreateHandler<NotImplementedYetHandler>},
//"import"
//"include"
{ "key", CreateHandler<NotImplementedYetHandler>},
{ "key", CreateHandler<KeyHandler>},
{ "namespace-alias", CreateHandler<NamespaceAliasHandler>},
{ "output", CreateHandler<OutputHandler>},
{ "param", CreateHandler<TopLevelVariableHandler<Param> >},