mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
OK, forget what I said about state machines, let just hack in some flags.
Initial work on CDATA section output. If I manually populate the set of cdata section elements, everything looks great, so I just need to hook that up. Added operator< to QName so I pop it in a std::set.
This commit is contained in:
parent
76acb7939f
commit
f6dfa127a1
3 changed files with 76 additions and 6 deletions
|
@ -16,11 +16,13 @@ class Output
|
|||
{
|
||||
public:
|
||||
typedef std::map<std::string, std::string> Settings;
|
||||
typedef std::set<QName> CDATAElements;
|
||||
|
||||
protected:
|
||||
Output() :
|
||||
buffering_(0),
|
||||
pending_element_(false),
|
||||
pending_text_(false),
|
||||
pending_attribute_(-1),
|
||||
text_mode_(false),
|
||||
warning_sink_(0)
|
||||
|
@ -57,7 +59,7 @@ public:
|
|||
if(is_buffering())
|
||||
return false;
|
||||
|
||||
flush_element();
|
||||
flush_current();
|
||||
|
||||
namespaceStack_.pushScope();
|
||||
if(!namespaceURI.empty())
|
||||
|
@ -85,7 +87,7 @@ public:
|
|||
if(pop_if_buffering())
|
||||
return;
|
||||
|
||||
flush_element();
|
||||
flush_current();
|
||||
|
||||
if(!text_mode_)
|
||||
{
|
||||
|
@ -172,8 +174,16 @@ public:
|
|||
return;
|
||||
} // if ...
|
||||
|
||||
if(!buffering_)
|
||||
do_characters(ch);
|
||||
if(buffering_)
|
||||
return;
|
||||
|
||||
if(!pending_text_)
|
||||
{
|
||||
pending_text_ = true;
|
||||
if(isCDATA())
|
||||
do_start_CDATA();
|
||||
} // if ...
|
||||
do_characters(ch);
|
||||
} // characters
|
||||
|
||||
void start_comment()
|
||||
|
@ -181,7 +191,7 @@ public:
|
|||
if(push_buffering())
|
||||
return;
|
||||
|
||||
flush_element();
|
||||
flush_current();
|
||||
} // start_comment
|
||||
|
||||
void end_comment()
|
||||
|
@ -203,7 +213,7 @@ public:
|
|||
if(push_buffering())
|
||||
return;
|
||||
|
||||
flush_element();
|
||||
flush_current();
|
||||
|
||||
target_ = target;
|
||||
} // start_processing_instruction
|
||||
|
@ -237,6 +247,8 @@ protected:
|
|||
virtual void do_start_element(const std::string& qName, const std::string& namespaceURI, const SAX::Attributes<std::string>& atts) = 0;
|
||||
virtual void do_end_element(const std::string& qName, const std::string& namespaceURI) = 0;
|
||||
virtual void do_characters(const std::string& ch) = 0;
|
||||
virtual void do_start_CDATA() = 0;
|
||||
virtual void do_end_CDATA() = 0;
|
||||
virtual void do_comment(const std::string& ch) = 0;
|
||||
virtual void do_processing_instruction(const std::string& target, const std::string& data) = 0;
|
||||
virtual void do_disableOutputEscaping(bool disable) = 0;
|
||||
|
@ -288,6 +300,18 @@ private:
|
|||
return (buffering_ != 0); // oh, Visual Studio how I curse you warning C4800
|
||||
} // pop_buffering
|
||||
|
||||
void flush_current()
|
||||
{
|
||||
if(pending_text_)
|
||||
{
|
||||
if(isCDATA())
|
||||
do_end_CDATA();
|
||||
pending_text_ = false;
|
||||
} // if ...
|
||||
|
||||
flush_element();
|
||||
} // flush_current
|
||||
|
||||
void flush_element()
|
||||
{
|
||||
if((!pending_element_) || (pending_attribute_ != -1))
|
||||
|
@ -307,6 +331,12 @@ private:
|
|||
pending_element_ = false;
|
||||
} // flush_element
|
||||
|
||||
bool isCDATA()
|
||||
{
|
||||
QName currentElement = element_stack_.top();
|
||||
return cdataElements_.find(currentElement) != cdataElements_.end();
|
||||
} // isCDATA
|
||||
|
||||
void addNamespaceDeclarations()
|
||||
{
|
||||
for(NamespaceStack::Scope::const_iterator n = namespaceStack_.begin(), ne = namespaceStack_.end(); n != ne; ++n)
|
||||
|
@ -332,6 +362,8 @@ private:
|
|||
int buffering_;
|
||||
bool pending_element_;
|
||||
int pending_attribute_;
|
||||
bool pending_text_;
|
||||
CDATAElements cdataElements_;
|
||||
std::stack<QName> element_stack_;
|
||||
std::string target_;
|
||||
SAX::AttributesImpl<std::string, Arabica::default_string_adaptor<std::string> > atts_;
|
||||
|
|
|
@ -51,8 +51,23 @@ struct QName
|
|||
}
|
||||
return QName(prefix, localName, namespaceURI);
|
||||
} // create
|
||||
|
||||
bool operator==(const QName& rhs) const
|
||||
{
|
||||
return (namespaceURI == rhs.namespaceURI) &&
|
||||
(localName == rhs.localName);
|
||||
} // operator==
|
||||
|
||||
bool operator<(const QName& rhs) const
|
||||
{
|
||||
if(namespaceURI == rhs.namespaceURI)
|
||||
return localName < rhs.localName;
|
||||
return namespaceURI < rhs.namespaceURI;
|
||||
} // operator<
|
||||
}; // struct QName
|
||||
|
||||
|
||||
|
||||
} // namespace XSLT
|
||||
} // namespace Arabica
|
||||
#endif
|
||||
|
|
|
@ -170,6 +170,18 @@ protected:
|
|||
stream_ << ch;
|
||||
} // characters
|
||||
|
||||
void do_start_CDATA()
|
||||
{
|
||||
close_element_if_empty();
|
||||
|
||||
stream_ << "<![CDATA[";
|
||||
} // do_start_CDATA
|
||||
|
||||
void do_end_CDATA()
|
||||
{
|
||||
stream_ << "]]>";
|
||||
} // do_end_CDATA
|
||||
|
||||
void do_comment(const std::string& ch)
|
||||
{
|
||||
close_element_if_empty();
|
||||
|
@ -335,6 +347,17 @@ protected:
|
|||
lc.setNodeValue(lc.getNodeValue() + ch);
|
||||
} // do_characters
|
||||
|
||||
void do_start_CDATA()
|
||||
{
|
||||
} // do_start_CDATA
|
||||
|
||||
void do_end_CDATA()
|
||||
{
|
||||
DOM::Node<std::string> lc = current().getLastChild();
|
||||
if(lc.getNodeType() == DOM::Node_base::TEXT_NODE)
|
||||
current().replaceChild(document().createCDATASection(lc.getNodeValue()), lc);
|
||||
} // do_end_CDATA
|
||||
|
||||
void do_comment(const std::string& ch)
|
||||
{
|
||||
current().appendChild(document().createComment(ch));
|
||||
|
|
Loading…
Reference in a new issue