mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
started work on xsl:key/key()
This commit is contained in:
parent
3e3447dcff
commit
4d9c2a485a
4 changed files with 128 additions and 1 deletions
66
include/XSLT/impl/handler/xslt_key_handler.hpp
Normal file
66
include/XSLT/impl/handler/xslt_key_handler.hpp
Normal 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
|
|
@ -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;
|
||||
|
|
53
include/XSLT/impl/xslt_key.hpp
Normal file
53
include/XSLT/impl/xslt_key.hpp
Normal 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
|
|
@ -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> >},
|
||||
|
|
Loading…
Reference in a new issue