mirror of
https://github.com/jezhiggins/arabica
synced 2025-02-11 08:48:06 +01:00
sink
This commit is contained in:
parent
3d0806460d
commit
efcb81b80c
8 changed files with 110 additions and 101 deletions
|
@ -57,9 +57,12 @@ public:
|
||||||
} // characters
|
} // characters
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Output::CDATAElements extractCDATAElements(const string_type& cdata_section_elements) const
|
typedef typename Output<string_type, string_adaptor>::CDATAElements CDATAElements;
|
||||||
|
typedef typename Output<string_type, string_adaptor>::Settings Settings;
|
||||||
|
|
||||||
|
CDATAElements extractCDATAElements(const string_type& cdata_section_elements) const
|
||||||
{
|
{
|
||||||
Output::CDATAElements elements;
|
CDATAElements elements;
|
||||||
|
|
||||||
if(cdata_section_elements.empty())
|
if(cdata_section_elements.empty())
|
||||||
return elements;
|
return elements;
|
||||||
|
@ -78,8 +81,8 @@ private:
|
||||||
} // extractCDATAElements
|
} // extractCDATAElements
|
||||||
|
|
||||||
CompilationContext<string_type, string_adaptor>& context_;
|
CompilationContext<string_type, string_adaptor>& context_;
|
||||||
Output::Settings settings_;
|
Settings settings_;
|
||||||
Output::CDATAElements cdataElements_;
|
CDATAElements cdataElements_;
|
||||||
}; // class OutputHandler
|
}; // class OutputHandler
|
||||||
|
|
||||||
} // namespace XSLT
|
} // namespace XSLT
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CompiledStylesheet : public Stylesheet
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompiledStylesheet() :
|
CompiledStylesheet() :
|
||||||
output_(new StreamSink(std::cout)),
|
output_(new StreamSink<std::string>(std::cout)),
|
||||||
error_output_(&std::cerr)
|
error_output_(&std::cerr)
|
||||||
{
|
{
|
||||||
} // CompiledStylesheet
|
} // CompiledStylesheet
|
||||||
|
@ -58,7 +58,7 @@ public:
|
||||||
set_parameter(name, Value(new StringValue(value)));
|
set_parameter(name, Value(new StringValue(value)));
|
||||||
} // set_parameter
|
} // set_parameter
|
||||||
|
|
||||||
virtual void set_output(Sink& sink)
|
virtual void set_output(Sink<std::string>& sink)
|
||||||
{
|
{
|
||||||
output_.reset(sink);
|
output_.reset(sink);
|
||||||
} // set_output
|
} // set_output
|
||||||
|
@ -135,7 +135,8 @@ public:
|
||||||
keys_.add(name, key);
|
keys_.add(name, key);
|
||||||
} // add_key
|
} // add_key
|
||||||
|
|
||||||
void output_settings(const Output::Settings& settings, const Output::CDATAElements& cdata_elements)
|
void output_settings(const Output<std::string, Arabica::default_string_adaptor<std::string> >::Settings& settings,
|
||||||
|
const Output<std::string, Arabica::default_string_adaptor<std::string> >::CDATAElements& cdata_elements)
|
||||||
{
|
{
|
||||||
output_settings_ = settings;
|
output_settings_ = settings;
|
||||||
output_cdata_elements_.insert(cdata_elements.begin(), cdata_elements.end());
|
output_cdata_elements_.insert(cdata_elements.begin(), cdata_elements.end());
|
||||||
|
@ -328,9 +329,9 @@ private:
|
||||||
mutable std::string current_mode_;
|
mutable std::string current_mode_;
|
||||||
mutable Precedence current_generation_;
|
mutable Precedence current_generation_;
|
||||||
|
|
||||||
Output::Settings output_settings_;
|
Output<std::string, Arabica::default_string_adaptor<std::string> >::Settings output_settings_;
|
||||||
Output::CDATAElements output_cdata_elements_;
|
Output<std::string, Arabica::default_string_adaptor<std::string> >::CDATAElements output_cdata_elements_;
|
||||||
SinkHolder output_;
|
SinkHolder<std::string, Arabica::default_string_adaptor<std::string> > output_;
|
||||||
mutable std::ostream* error_output_;
|
mutable std::ostream* error_output_;
|
||||||
}; // class CompiledStylesheet
|
}; // class CompiledStylesheet
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
virtual const std::string& name() const = 0;
|
virtual const std::string& name() const = 0;
|
||||||
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
|
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
|
||||||
ExecutionContext& context,
|
ExecutionContext& context,
|
||||||
DOMSink& sink) const = 0;
|
DOMSink<std::string>& sink) const = 0;
|
||||||
virtual const Precedence& precedence() const = 0;
|
virtual const Precedence& precedence() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -35,7 +35,7 @@ class ExecutionContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExecutionContext(const CompiledStylesheet& stylesheet,
|
ExecutionContext(const CompiledStylesheet& stylesheet,
|
||||||
Sink& output,
|
Sink<std::string>& output,
|
||||||
std::ostream& error_output) :
|
std::ostream& error_output) :
|
||||||
stylesheet_(stylesheet),
|
stylesheet_(stylesheet),
|
||||||
sink_(output.asOutput()),
|
sink_(output.asOutput()),
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
message_sink_.asOutput().set_warning_sink(message_sink_.asOutput());
|
message_sink_.asOutput().set_warning_sink(message_sink_.asOutput());
|
||||||
} // ExecutionContext
|
} // ExecutionContext
|
||||||
|
|
||||||
ExecutionContext(Sink& output,
|
ExecutionContext(Sink<std::string>& output,
|
||||||
ExecutionContext& rhs) :
|
ExecutionContext& rhs) :
|
||||||
stylesheet_(rhs.stylesheet_),
|
stylesheet_(rhs.stylesheet_),
|
||||||
stack_(rhs.stack_),
|
stack_(rhs.stack_),
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
|
|
||||||
const CompiledStylesheet& stylesheet() const { return stylesheet_; }
|
const CompiledStylesheet& stylesheet() const { return stylesheet_; }
|
||||||
|
|
||||||
Output& sink()
|
Output<std::string, Arabica::default_string_adaptor<std::string> >& sink()
|
||||||
{
|
{
|
||||||
return !to_msg_ ? sink_ : message_sink_.asOutput();
|
return !to_msg_ ? sink_ : message_sink_.asOutput();
|
||||||
} // sink
|
} // sink
|
||||||
|
@ -103,8 +103,8 @@ private:
|
||||||
const CompiledStylesheet& stylesheet_;
|
const CompiledStylesheet& stylesheet_;
|
||||||
VariableStack stack_;
|
VariableStack stack_;
|
||||||
Arabica::XPath::ExecutionContext<std::string> xpathContext_;
|
Arabica::XPath::ExecutionContext<std::string> xpathContext_;
|
||||||
Output& sink_;
|
Output<std::string, Arabica::default_string_adaptor<std::string> >& sink_;
|
||||||
StreamSink message_sink_;
|
StreamSink<std::string> message_sink_;
|
||||||
int to_msg_;
|
int to_msg_;
|
||||||
|
|
||||||
friend class StackFrame;
|
friend class StackFrame;
|
||||||
|
@ -149,7 +149,7 @@ private:
|
||||||
} // VariableClosure
|
} // VariableClosure
|
||||||
|
|
||||||
const Variable_declaration& var_;
|
const Variable_declaration& var_;
|
||||||
mutable DOMSink sink_;
|
mutable DOMSink<std::string> sink_;
|
||||||
const DOM::Node<std::string> node_;
|
const DOM::Node<std::string> node_;
|
||||||
mutable ExecutionContext context_;
|
mutable ExecutionContext context_;
|
||||||
mutable Arabica::XPath::XPathValue<std::string> value_;
|
mutable Arabica::XPath::XPathValue<std::string> value_;
|
||||||
|
|
|
@ -12,10 +12,11 @@ namespace Arabica
|
||||||
namespace XSLT
|
namespace XSLT
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<class string_type, class string_adaptor>
|
||||||
class Output
|
class Output
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string, std::string> Settings;
|
typedef std::map<string_type, string_type> Settings;
|
||||||
typedef std::set<QName> CDATAElements;
|
typedef std::set<QName> CDATAElements;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -49,13 +50,13 @@ public:
|
||||||
do_end_document();
|
do_end_document();
|
||||||
} // end_document
|
} // end_document
|
||||||
|
|
||||||
bool start_element(const std::string& qName, const std::string& namespaceURI)
|
bool start_element(const string_type& qName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
QName en = QName::create(qName, namespaceURI);
|
QName en = QName::create(qName, namespaceURI);
|
||||||
return start_element(en.prefix, en.localName, en.namespaceURI);
|
return start_element(en.prefix, en.localName, en.namespaceURI);
|
||||||
} // start_element
|
} // start_element
|
||||||
|
|
||||||
bool start_element(const std::string& prefix, const std::string& localName, const std::string& namespaceURI)
|
bool start_element(const string_type& prefix, const string_type& localName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
if(is_buffering())
|
if(is_buffering())
|
||||||
return false;
|
return false;
|
||||||
|
@ -66,7 +67,7 @@ public:
|
||||||
if(!namespaceURI.empty())
|
if(!namespaceURI.empty())
|
||||||
namespaceStack_.declareNamespace(prefix, namespaceURI);
|
namespaceStack_.declareNamespace(prefix, namespaceURI);
|
||||||
|
|
||||||
std::string mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
||||||
|
|
||||||
element_stack_.push(QName(mapped_prefix, localName, namespaceURI));
|
element_stack_.push(QName(mapped_prefix, localName, namespaceURI));
|
||||||
|
|
||||||
|
@ -77,13 +78,13 @@ public:
|
||||||
return true;
|
return true;
|
||||||
} // start_element
|
} // start_element
|
||||||
|
|
||||||
void end_element(const std::string& qName, const std::string& namespaceURI)
|
void end_element(const string_type& qName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
QName en = QName::create(qName, namespaceURI);
|
QName en = QName::create(qName, namespaceURI);
|
||||||
end_element(en.prefix, en.localName, en.namespaceURI);
|
end_element(en.prefix, en.localName, en.namespaceURI);
|
||||||
} // end_element
|
} // end_element
|
||||||
|
|
||||||
void end_element(const std::string& /* prefix */, const std::string& localName, const std::string& namespaceURI)
|
void end_element(const string_type& /* prefix */, const string_type& localName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
if(pop_if_buffering())
|
if(pop_if_buffering())
|
||||||
return;
|
return;
|
||||||
|
@ -92,7 +93,7 @@ public:
|
||||||
|
|
||||||
if(!text_mode_)
|
if(!text_mode_)
|
||||||
{
|
{
|
||||||
std::string mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
||||||
do_end_element((!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName, namespaceURI);
|
do_end_element((!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName, namespaceURI);
|
||||||
element_stack_.pop();
|
element_stack_.pop();
|
||||||
} // end_element
|
} // end_element
|
||||||
|
@ -100,13 +101,13 @@ public:
|
||||||
namespaceStack_.popScope();
|
namespaceStack_.popScope();
|
||||||
} // end_element
|
} // end_element
|
||||||
|
|
||||||
void start_attribute(const std::string& qName, const std::string& namespaceURI)
|
void start_attribute(const string_type& qName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
QName qn = QName::create(qName, namespaceURI);
|
QName qn = QName::create(qName, namespaceURI);
|
||||||
start_attribute(qn.prefix, qn.localName, qn.namespaceURI);
|
start_attribute(qn.prefix, qn.localName, qn.namespaceURI);
|
||||||
} // start_attribute
|
} // start_attribute
|
||||||
|
|
||||||
void start_attribute(const std::string& prefix, const std::string& localName, const std::string& namespaceURI)
|
void start_attribute(const string_type& prefix, const string_type& localName, const string_type& namespaceURI)
|
||||||
{
|
{
|
||||||
if(push_buffering())
|
if(push_buffering())
|
||||||
return;
|
return;
|
||||||
|
@ -120,8 +121,8 @@ public:
|
||||||
if(!namespaceURI.empty())
|
if(!namespaceURI.empty())
|
||||||
namespaceStack_.declareNamespace(prefix, namespaceURI, true);
|
namespaceStack_.declareNamespace(prefix, namespaceURI, true);
|
||||||
|
|
||||||
std::string mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
||||||
std::string qName = (!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName;
|
string_type qName = (!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName;
|
||||||
|
|
||||||
atts_.addOrReplaceAttribute(namespaceURI,
|
atts_.addOrReplaceAttribute(namespaceURI,
|
||||||
localName,
|
localName,
|
||||||
|
@ -144,10 +145,10 @@ public:
|
||||||
pending_attribute_ = -1;
|
pending_attribute_ = -1;
|
||||||
} // end_attribute
|
} // end_attribute
|
||||||
|
|
||||||
void add_attribute(const std::string& uri,
|
void add_attribute(const string_type& uri,
|
||||||
const std::string& localName,
|
const string_type& localName,
|
||||||
const std::string& qName,
|
const string_type& qName,
|
||||||
const std::string& value)
|
const string_type& value)
|
||||||
{
|
{
|
||||||
if(!pending_element_)
|
if(!pending_element_)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +159,7 @@ public:
|
||||||
atts_.addAttribute(uri, localName, qName, "", value);
|
atts_.addAttribute(uri, localName, qName, "", value);
|
||||||
} // add_attribute
|
} // add_attribute
|
||||||
|
|
||||||
void characters(const std::string& ch)
|
void characters(const string_type& ch)
|
||||||
{
|
{
|
||||||
if(buffering_)
|
if(buffering_)
|
||||||
{
|
{
|
||||||
|
@ -202,14 +203,14 @@ public:
|
||||||
|
|
||||||
if(!text_mode_)
|
if(!text_mode_)
|
||||||
{
|
{
|
||||||
std::string comment = escape(buffer_.str(), "--", "- -");
|
string_type comment = escape(buffer_.str(), "--", "- -");
|
||||||
if(comment.length() && *(comment.rbegin()) == '-')
|
if(comment.length() && *(comment.rbegin()) == '-')
|
||||||
comment.append(" ");
|
comment.append(" ");
|
||||||
do_comment(comment);
|
do_comment(comment);
|
||||||
} // if ...
|
} // if ...
|
||||||
} // end_comment
|
} // end_comment
|
||||||
|
|
||||||
void start_processing_instruction(const std::string& target)
|
void start_processing_instruction(const string_type& target)
|
||||||
{
|
{
|
||||||
if(push_buffering())
|
if(push_buffering())
|
||||||
return;
|
return;
|
||||||
|
@ -226,7 +227,7 @@ public:
|
||||||
|
|
||||||
if(!text_mode_)
|
if(!text_mode_)
|
||||||
{
|
{
|
||||||
std::string data = escape(buffer_.str(), "?>", "? >");
|
string_type data = escape(buffer_.str(), "?>", "? >");
|
||||||
do_processing_instruction(target_, data);
|
do_processing_instruction(target_, data);
|
||||||
} // if ...
|
} // if ...
|
||||||
} // end_processing_instruction
|
} // end_processing_instruction
|
||||||
|
@ -245,21 +246,21 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void do_start_document(const Settings& settings) = 0;
|
virtual void do_start_document(const Settings& settings) = 0;
|
||||||
virtual void do_end_document() = 0;
|
virtual void do_end_document() = 0;
|
||||||
virtual void do_start_element(const std::string& qName, const std::string& namespaceURI, const SAX::Attributes<std::string>& atts) = 0;
|
virtual void do_start_element(const string_type& qName, const string_type& namespaceURI, const SAX::Attributes<string_type, string_adaptor>& atts) = 0;
|
||||||
virtual void do_end_element(const std::string& qName, const std::string& namespaceURI) = 0;
|
virtual void do_end_element(const string_type& qName, const string_type& namespaceURI) = 0;
|
||||||
virtual void do_characters(const std::string& ch) = 0;
|
virtual void do_characters(const string_type& ch) = 0;
|
||||||
virtual void do_start_CDATA() = 0;
|
virtual void do_start_CDATA() = 0;
|
||||||
virtual void do_end_CDATA() = 0;
|
virtual void do_end_CDATA() = 0;
|
||||||
virtual void do_comment(const std::string& ch) = 0;
|
virtual void do_comment(const string_type& ch) = 0;
|
||||||
virtual void do_processing_instruction(const std::string& target, const std::string& data) = 0;
|
virtual void do_processing_instruction(const string_type& target, const string_type& data) = 0;
|
||||||
virtual void do_disableOutputEscaping(bool disable) = 0;
|
virtual void do_disableOutputEscaping(bool disable) = 0;
|
||||||
virtual bool want_namespace_declarations() const = 0;
|
virtual bool want_namespace_declarations() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string escape(std::string str, const std::string& t, const std::string& r) const
|
string_type escape(string_type str, const string_type& t, const string_type& r) const
|
||||||
{
|
{
|
||||||
std::string::size_type naughty = str.find(t);
|
string_type::size_type naughty = str.find(t);
|
||||||
while(naughty != std::string::npos)
|
while(naughty != string_type::npos)
|
||||||
{
|
{
|
||||||
str.replace(naughty, t.length(), r, 0, r.length());
|
str.replace(naughty, t.length(), r, 0, r.length());
|
||||||
naughty = str.find(t, naughty);
|
naughty = str.find(t, naughty);
|
||||||
|
@ -347,7 +348,7 @@ private:
|
||||||
if(n->first == "xml")
|
if(n->first == "xml")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string qName = (n->first.empty()) ? "xmlns" : "xmlns:" + n->first;
|
string_type qName = (n->first.empty()) ? "xmlns" : "xmlns:" + n->first;
|
||||||
atts_.addAttribute("http://www.w3.org/2000/xmlns",
|
atts_.addAttribute("http://www.w3.org/2000/xmlns",
|
||||||
n->first,
|
n->first,
|
||||||
qName,
|
qName,
|
||||||
|
@ -356,7 +357,7 @@ private:
|
||||||
}
|
}
|
||||||
} // addNamespaceDeclarations
|
} // addNamespaceDeclarations
|
||||||
|
|
||||||
void warning(const std::string& warning_message)
|
void warning(const string_type& warning_message)
|
||||||
{
|
{
|
||||||
warning_sink_->characters(warning_message);
|
warning_sink_->characters(warning_message);
|
||||||
warning_sink_->characters("\n");
|
warning_sink_->characters("\n");
|
||||||
|
@ -370,8 +371,8 @@ private:
|
||||||
Output* warning_sink_;
|
Output* warning_sink_;
|
||||||
CDATAElements cdataElements_;
|
CDATAElements cdataElements_;
|
||||||
std::stack<QName> element_stack_;
|
std::stack<QName> element_stack_;
|
||||||
std::string target_;
|
string_type target_;
|
||||||
SAX::AttributesImpl<std::string, Arabica::default_string_adaptor<std::string> > atts_;
|
SAX::AttributesImpl<string_type, string_adaptor> atts_;
|
||||||
std::stringstream buffer_;
|
std::stringstream buffer_;
|
||||||
NamespaceStack namespaceStack_;
|
NamespaceStack namespaceStack_;
|
||||||
}; // class Output
|
}; // class Output
|
||||||
|
|
|
@ -15,24 +15,26 @@ namespace Arabica
|
||||||
namespace XSLT
|
namespace XSLT
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||||
class Sink
|
class Sink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Sink() { }
|
virtual ~Sink() { }
|
||||||
|
|
||||||
virtual Output& asOutput() = 0;
|
virtual Output<string_type, string_adaptor>& asOutput() = 0;
|
||||||
}; // class Sink
|
}; // class Sink
|
||||||
|
|
||||||
|
template<class string_type, class string_adaptor>
|
||||||
class SinkHolder
|
class SinkHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SinkHolder(Sink* sink) :
|
SinkHolder(Sink<string_type, string_adaptor>* sink) :
|
||||||
sink_(sink),
|
sink_(sink),
|
||||||
owned_(true)
|
owned_(true)
|
||||||
{
|
{
|
||||||
} // SinkHolder
|
} // SinkHolder
|
||||||
|
|
||||||
SinkHolder(Sink& sink) :
|
SinkHolder(Sink<string_type, string_adaptor>& sink) :
|
||||||
sink_(&sink),
|
sink_(&sink),
|
||||||
owned_(false)
|
owned_(false)
|
||||||
{
|
{
|
||||||
|
@ -43,21 +45,21 @@ public:
|
||||||
clear();
|
clear();
|
||||||
} // ~SinkHolder
|
} // ~SinkHolder
|
||||||
|
|
||||||
void reset(Sink* sink)
|
void reset(Sink<string_type, string_adaptor>* sink)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
sink_ = sink;
|
sink_ = sink;
|
||||||
owned_ = true;
|
owned_ = true;
|
||||||
} // assign
|
} // assign
|
||||||
|
|
||||||
void reset(Sink& sink)
|
void reset(Sink<string_type, string_adaptor>& sink)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
sink_ = &sink;
|
sink_ = &sink;
|
||||||
owned_ = false;
|
owned_ = false;
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
Sink& get() const
|
Sink<string_type, string_adaptor>& get() const
|
||||||
{
|
{
|
||||||
return *sink_;
|
return *sink_;
|
||||||
} // get
|
} // get
|
||||||
|
@ -69,7 +71,7 @@ private:
|
||||||
delete sink_;
|
delete sink_;
|
||||||
} // clear
|
} // clear
|
||||||
|
|
||||||
Sink* sink_;
|
Sink<string_type, string_adaptor>* sink_;
|
||||||
bool owned_;
|
bool owned_;
|
||||||
|
|
||||||
SinkHolder(const SinkHolder&);
|
SinkHolder(const SinkHolder&);
|
||||||
|
@ -77,7 +79,8 @@ private:
|
||||||
SinkHolder& operator=(const SinkHolder&);
|
SinkHolder& operator=(const SinkHolder&);
|
||||||
}; // class SinkHolder
|
}; // class SinkHolder
|
||||||
|
|
||||||
class StreamSink : public Sink, private Output
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||||
|
class StreamSink : public Sink<string_type, string_adaptor>, private Output<string_type, string_adaptor>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StreamSink(std::ostream& stream) :
|
StreamSink(std::ostream& stream) :
|
||||||
|
@ -108,7 +111,7 @@ public:
|
||||||
stream_.flush();
|
stream_.flush();
|
||||||
} // ~StreamSink
|
} // ~StreamSink
|
||||||
|
|
||||||
virtual Output& asOutput() { return *this; }
|
virtual Output<string_type, string_adaptor>& asOutput() { return *this; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void do_start_document(const Settings& settings)
|
void do_start_document(const Settings& settings)
|
||||||
|
@ -123,9 +126,9 @@ protected:
|
||||||
{
|
{
|
||||||
} // do_end_document
|
} // do_end_document
|
||||||
|
|
||||||
void do_start_element(const std::string& qName,
|
void do_start_element(const string_type& qName,
|
||||||
const std::string& /* namespaceURI */,
|
const string_type& /* namespaceURI */,
|
||||||
const SAX::Attributes<std::string>& atts)
|
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||||
{
|
{
|
||||||
if(!seen_root_)
|
if(!seen_root_)
|
||||||
do_decl(qName);
|
do_decl(qName);
|
||||||
|
@ -138,15 +141,15 @@ protected:
|
||||||
for(int a = 0; a < atts.getLength(); ++a)
|
for(int a = 0; a < atts.getLength(); ++a)
|
||||||
{
|
{
|
||||||
stream_ << ' ' << atts.getQName(a) << '=' << '\"';
|
stream_ << ' ' << atts.getQName(a) << '=' << '\"';
|
||||||
std::string ch = atts.getValue(a);
|
string_type ch = atts.getValue(a);
|
||||||
std::for_each(ch.begin(), ch.end(), Arabica::XML::attribute_escaper<char>(stream_));
|
std::for_each(ch.begin(), ch.end(), Arabica::XML::attribute_escaper<char>(stream_));
|
||||||
stream_ << '\"';
|
stream_ << '\"';
|
||||||
}
|
}
|
||||||
empty_ = true;
|
empty_ = true;
|
||||||
} // do_start_element
|
} // do_start_element
|
||||||
|
|
||||||
void do_end_element(const std::string& qName,
|
void do_end_element(const string_type& qName,
|
||||||
const std::string& /* namespaceURI */)
|
const string_type& /* namespaceURI */)
|
||||||
{
|
{
|
||||||
if(!seen_root_)
|
if(!seen_root_)
|
||||||
do_decl("");
|
do_decl("");
|
||||||
|
@ -163,7 +166,7 @@ protected:
|
||||||
empty_ = false;
|
empty_ = false;
|
||||||
} // do_end_element
|
} // do_end_element
|
||||||
|
|
||||||
void do_characters(const std::string& ch)
|
void do_characters(const string_type& ch)
|
||||||
{
|
{
|
||||||
close_element_if_empty();
|
close_element_if_empty();
|
||||||
|
|
||||||
|
@ -172,7 +175,7 @@ protected:
|
||||||
else if(in_cdata_)
|
else if(in_cdata_)
|
||||||
{
|
{
|
||||||
size_t breakAt = ch.find("]]>");
|
size_t breakAt = ch.find("]]>");
|
||||||
if(breakAt == std::string::npos)
|
if(breakAt == string_type::npos)
|
||||||
{
|
{
|
||||||
stream_ << ch;
|
stream_ << ch;
|
||||||
return;
|
return;
|
||||||
|
@ -187,7 +190,7 @@ protected:
|
||||||
do_start_CDATA();
|
do_start_CDATA();
|
||||||
breakAt = ch.find("]]>", breakAt);
|
breakAt = ch.find("]]>", breakAt);
|
||||||
}
|
}
|
||||||
while(breakAt != std::string::npos);
|
while(breakAt != string_type::npos);
|
||||||
stream_ << ch.substr(start);
|
stream_ << ch.substr(start);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -208,7 +211,7 @@ protected:
|
||||||
stream_ << "]]>";
|
stream_ << "]]>";
|
||||||
} // do_end_CDATA
|
} // do_end_CDATA
|
||||||
|
|
||||||
void do_comment(const std::string& ch)
|
void do_comment(const string_type& ch)
|
||||||
{
|
{
|
||||||
close_element_if_empty();
|
close_element_if_empty();
|
||||||
|
|
||||||
|
@ -217,8 +220,8 @@ protected:
|
||||||
<< "-->";
|
<< "-->";
|
||||||
} // do_comment
|
} // do_comment
|
||||||
|
|
||||||
void do_processing_instruction(const std::string& target,
|
void do_processing_instruction(const string_type& target,
|
||||||
const std::string& data)
|
const string_type& data)
|
||||||
{
|
{
|
||||||
close_element_if_empty();
|
close_element_if_empty();
|
||||||
|
|
||||||
|
@ -280,19 +283,19 @@ private:
|
||||||
out_again_ = true;
|
out_again_ = true;
|
||||||
} // outdent
|
} // outdent
|
||||||
|
|
||||||
void do_decl(const std::string& qName)
|
void do_decl(const string_type& qName)
|
||||||
{
|
{
|
||||||
if((setting("method") == "text") || (setting("omit-xml-declaration") == "yes"))
|
if((setting("method") == "text") || (setting("omit-xml-declaration") == "yes"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string version = setting("version");
|
string_type version = setting("version");
|
||||||
if(version.empty())
|
if(version.empty())
|
||||||
version = "1.0";
|
version = "1.0";
|
||||||
stream_ << "<?xml version=\"" << version << "\"";
|
stream_ << "<?xml version=\"" << version << "\"";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string s = setting("standalone");
|
string_type s = setting("standalone");
|
||||||
if(!s.empty())
|
if(!s.empty())
|
||||||
stream_ << " standalone=\"" << s << "\"";
|
stream_ << " standalone=\"" << s << "\"";
|
||||||
}
|
}
|
||||||
|
@ -300,8 +303,8 @@ private:
|
||||||
|
|
||||||
if(!qName.empty())
|
if(!qName.empty())
|
||||||
{
|
{
|
||||||
std::string pub = setting("doctype-public");
|
string_type pub = setting("doctype-public");
|
||||||
std::string sys = setting("doctype-system");
|
string_type sys = setting("doctype-system");
|
||||||
|
|
||||||
if(!sys.empty())
|
if(!sys.empty())
|
||||||
{
|
{
|
||||||
|
@ -315,7 +318,7 @@ private:
|
||||||
seen_root_ = true;
|
seen_root_ = true;
|
||||||
} // do_decl
|
} // do_decl
|
||||||
|
|
||||||
std::string setting(const std::string& name)
|
string_type setting(const string_type& name)
|
||||||
{
|
{
|
||||||
Settings::const_iterator i = settings_.find(name);
|
Settings::const_iterator i = settings_.find(name);
|
||||||
if(i == settings_.end())
|
if(i == settings_.end())
|
||||||
|
@ -336,7 +339,8 @@ private:
|
||||||
StreamSink& operator=(const StreamSink&);
|
StreamSink& operator=(const StreamSink&);
|
||||||
}; // class StreamSink
|
}; // class StreamSink
|
||||||
|
|
||||||
class DOMSink : public Sink, private Output
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||||
|
class DOMSink : public Sink<string_type, string_adaptor>, private Output<string_type, string_adaptor>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DOMSink() :
|
DOMSink() :
|
||||||
|
@ -350,7 +354,7 @@ public:
|
||||||
} // ~DOMSink
|
} // ~DOMSink
|
||||||
|
|
||||||
virtual Output& asOutput() { return *this; }
|
virtual Output& asOutput() { return *this; }
|
||||||
DOM::Node<std::string> node() const { return documentFrag_; }
|
DOM::Node<string_type, string_adaptor> node() const { return documentFrag_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void do_start_document(const Settings& settings)
|
void do_start_document(const Settings& settings)
|
||||||
|
@ -365,9 +369,9 @@ protected:
|
||||||
{
|
{
|
||||||
} // do_end_document
|
} // do_end_document
|
||||||
|
|
||||||
void do_characters(const std::string& ch)
|
void do_characters(const string_type& ch)
|
||||||
{
|
{
|
||||||
DOM::Node<std::string> lc = current().getLastChild();
|
DOM::Node<string_type> lc = current().getLastChild();
|
||||||
if(lc == 0 || lc.getNodeType() != DOM::Node_base::TEXT_NODE)
|
if(lc == 0 || lc.getNodeType() != DOM::Node_base::TEXT_NODE)
|
||||||
current().appendChild(document().createTextNode(ch));
|
current().appendChild(document().createTextNode(ch));
|
||||||
else
|
else
|
||||||
|
@ -380,18 +384,18 @@ protected:
|
||||||
|
|
||||||
void do_end_CDATA()
|
void do_end_CDATA()
|
||||||
{
|
{
|
||||||
DOM::Node<std::string> lc = current().getLastChild();
|
DOM::Node<string_type> lc = current().getLastChild();
|
||||||
if(lc.getNodeType() == DOM::Node_base::TEXT_NODE)
|
if(lc.getNodeType() == DOM::Node_base::TEXT_NODE)
|
||||||
current().replaceChild(document().createCDATASection(lc.getNodeValue()), lc);
|
current().replaceChild(document().createCDATASection(lc.getNodeValue()), lc);
|
||||||
} // do_end_CDATA
|
} // do_end_CDATA
|
||||||
|
|
||||||
void do_comment(const std::string& ch)
|
void do_comment(const string_type& ch)
|
||||||
{
|
{
|
||||||
current().appendChild(document().createComment(ch));
|
current().appendChild(document().createComment(ch));
|
||||||
} // do_comment
|
} // do_comment
|
||||||
|
|
||||||
void do_processing_instruction(const std::string& target,
|
void do_processing_instruction(const string_type& target,
|
||||||
const std::string& data)
|
const string_type& data)
|
||||||
{
|
{
|
||||||
current().appendChild(document().createProcessingInstruction(target, data));
|
current().appendChild(document().createProcessingInstruction(target, data));
|
||||||
} // do_processing_instruction
|
} // do_processing_instruction
|
||||||
|
@ -400,12 +404,12 @@ protected:
|
||||||
|
|
||||||
bool want_namespace_declarations() const { return false; }
|
bool want_namespace_declarations() const { return false; }
|
||||||
|
|
||||||
void do_start_element(const std::string& qName,
|
void do_start_element(const string_type& qName,
|
||||||
const std::string& namespaceURI,
|
const string_type& namespaceURI,
|
||||||
const SAX::Attributes<std::string>& atts)
|
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||||
{
|
{
|
||||||
indent();
|
indent();
|
||||||
DOM::Element<std::string> elem = document().createElementNS(namespaceURI, qName);
|
DOM::Element<string_type, string_adaptor> elem = document().createElementNS(namespaceURI, qName);
|
||||||
current().appendChild(elem);
|
current().appendChild(elem);
|
||||||
|
|
||||||
// attributes here
|
// attributes here
|
||||||
|
@ -415,25 +419,25 @@ protected:
|
||||||
current_ = elem;
|
current_ = elem;
|
||||||
} // do_start_element
|
} // do_start_element
|
||||||
|
|
||||||
void do_end_element(const std::string& /* qName */,
|
void do_end_element(const string_type& /* qName */,
|
||||||
const std::string& /* namespaceURI */)
|
const string_type& /* namespaceURI */)
|
||||||
{
|
{
|
||||||
outdent();
|
outdent();
|
||||||
current_ = current_.getParentNode();
|
current_ = current_.getParentNode();
|
||||||
} // do_end_element
|
} // do_end_element
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DOM::Document<std::string>& document()
|
DOM::Document<string_type>& document()
|
||||||
{
|
{
|
||||||
if(document_ != 0)
|
if(document_ != 0)
|
||||||
return document_;
|
return document_;
|
||||||
|
|
||||||
DOM::DOMImplementation<std::string> di = SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
|
DOM::DOMImplementation<string_type, string_adaptor> di = SimpleDOM::DOMImplementation<string_type, string_adaptor>::getDOMImplementation();
|
||||||
document_ = di.createDocument("", "", 0);
|
document_ = di.createDocument("", "", 0);
|
||||||
return document_;
|
return document_;
|
||||||
} // document
|
} // document
|
||||||
|
|
||||||
DOM::Node<std::string>& current()
|
DOM::Node<string_type>& current()
|
||||||
{
|
{
|
||||||
if(current_ != 0)
|
if(current_ != 0)
|
||||||
return current_;
|
return current_;
|
||||||
|
@ -448,11 +452,11 @@ private:
|
||||||
if(indent_ == -1)
|
if(indent_ == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string sps;
|
string_type sps;
|
||||||
if(indent_ != 0)
|
if(indent_ != 0)
|
||||||
{
|
{
|
||||||
sps += '\n';
|
sps += '\n';
|
||||||
std::fill_n(std::back_inserter<std::string>(sps), indent_, ' ');
|
std::fill_n(std::back_inserter<string_type>(sps), indent_, ' ');
|
||||||
do_characters(sps);
|
do_characters(sps);
|
||||||
} // if ...
|
} // if ...
|
||||||
|
|
||||||
|
@ -473,9 +477,9 @@ private:
|
||||||
out_again_ = true;
|
out_again_ = true;
|
||||||
} // outdent
|
} // outdent
|
||||||
|
|
||||||
DOM::Document<std::string> document_;
|
DOM::Document<string_type, string_adaptor> document_;
|
||||||
DOM::DocumentFragment<std::string> documentFrag_;
|
DOM::DocumentFragment<string_type, string_adaptor> documentFrag_;
|
||||||
DOM::Node<std::string> current_;
|
DOM::Node<string_type, string_adaptor> current_;
|
||||||
|
|
||||||
int indent_;
|
int indent_;
|
||||||
bool out_again_;
|
bool out_again_;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace XSLT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <DOM/Node.hpp>
|
#include <DOM/Node.hpp>
|
||||||
class Sink;
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > class Sink;
|
||||||
|
|
||||||
class Stylesheet
|
class Stylesheet
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ public:
|
||||||
virtual void set_parameter(const std::string& name, const char* value) = 0;
|
virtual void set_parameter(const std::string& name, const char* value) = 0;
|
||||||
virtual void set_parameter(const std::string& name, const std::string& value) = 0;
|
virtual void set_parameter(const std::string& name, const std::string& value) = 0;
|
||||||
|
|
||||||
virtual void set_output(Sink& sink) = 0;
|
virtual void set_output(Sink<std::string>& sink) = 0;
|
||||||
|
|
||||||
virtual void set_error_output(std::ostream& os) = 0;
|
virtual void set_error_output(std::ostream& os) = 0;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
virtual const string_type& name() const { return name_; }
|
virtual const string_type& name() const { return name_; }
|
||||||
virtual Arabica::XPath::XPathValue<string_type, string_adaptor> value(const DOM::Node<string_type, string_adaptor>& /* node */,
|
virtual Arabica::XPath::XPathValue<string_type, string_adaptor> value(const DOM::Node<string_type, string_adaptor>& /* node */,
|
||||||
ExecutionContext& /* context */,
|
ExecutionContext& /* context */,
|
||||||
DOMSink& /* sink */) const
|
DOMSink<string_type, string_adaptor>& /* sink */) const
|
||||||
{
|
{
|
||||||
return value_;
|
return value_;
|
||||||
} // value
|
} // value
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
|
|
||||||
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
|
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
|
||||||
ExecutionContext& context,
|
ExecutionContext& context,
|
||||||
DOMSink& sink) const
|
DOMSink<std::string>& sink) const
|
||||||
{
|
{
|
||||||
if(select_)
|
if(select_)
|
||||||
return select_->evaluate(node, context.xpathContext());
|
return select_->evaluate(node, context.xpathContext());
|
||||||
|
|
Loading…
Add table
Reference in a new issue