mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-30 08:38:15 +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:
|
public:
|
||||||
typedef std::map<std::string, std::string> Settings;
|
typedef std::map<std::string, std::string> Settings;
|
||||||
|
typedef std::set<QName> CDATAElements;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Output() :
|
Output() :
|
||||||
buffering_(0),
|
buffering_(0),
|
||||||
pending_element_(false),
|
pending_element_(false),
|
||||||
|
pending_text_(false),
|
||||||
pending_attribute_(-1),
|
pending_attribute_(-1),
|
||||||
text_mode_(false),
|
text_mode_(false),
|
||||||
warning_sink_(0)
|
warning_sink_(0)
|
||||||
|
@ -57,7 +59,7 @@ public:
|
||||||
if(is_buffering())
|
if(is_buffering())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
flush_element();
|
flush_current();
|
||||||
|
|
||||||
namespaceStack_.pushScope();
|
namespaceStack_.pushScope();
|
||||||
if(!namespaceURI.empty())
|
if(!namespaceURI.empty())
|
||||||
|
@ -85,7 +87,7 @@ public:
|
||||||
if(pop_if_buffering())
|
if(pop_if_buffering())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_element();
|
flush_current();
|
||||||
|
|
||||||
if(!text_mode_)
|
if(!text_mode_)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +174,15 @@ public:
|
||||||
return;
|
return;
|
||||||
} // if ...
|
} // if ...
|
||||||
|
|
||||||
if(!buffering_)
|
if(buffering_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!pending_text_)
|
||||||
|
{
|
||||||
|
pending_text_ = true;
|
||||||
|
if(isCDATA())
|
||||||
|
do_start_CDATA();
|
||||||
|
} // if ...
|
||||||
do_characters(ch);
|
do_characters(ch);
|
||||||
} // characters
|
} // characters
|
||||||
|
|
||||||
|
@ -181,7 +191,7 @@ public:
|
||||||
if(push_buffering())
|
if(push_buffering())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_element();
|
flush_current();
|
||||||
} // start_comment
|
} // start_comment
|
||||||
|
|
||||||
void end_comment()
|
void end_comment()
|
||||||
|
@ -203,7 +213,7 @@ public:
|
||||||
if(push_buffering())
|
if(push_buffering())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_element();
|
flush_current();
|
||||||
|
|
||||||
target_ = target;
|
target_ = target;
|
||||||
} // start_processing_instruction
|
} // 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_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_end_element(const std::string& qName, const std::string& namespaceURI) = 0;
|
||||||
virtual void do_characters(const std::string& ch) = 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_comment(const std::string& ch) = 0;
|
||||||
virtual void do_processing_instruction(const std::string& target, const std::string& data) = 0;
|
virtual void do_processing_instruction(const std::string& target, const std::string& data) = 0;
|
||||||
virtual void do_disableOutputEscaping(bool disable) = 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
|
return (buffering_ != 0); // oh, Visual Studio how I curse you warning C4800
|
||||||
} // pop_buffering
|
} // pop_buffering
|
||||||
|
|
||||||
|
void flush_current()
|
||||||
|
{
|
||||||
|
if(pending_text_)
|
||||||
|
{
|
||||||
|
if(isCDATA())
|
||||||
|
do_end_CDATA();
|
||||||
|
pending_text_ = false;
|
||||||
|
} // if ...
|
||||||
|
|
||||||
|
flush_element();
|
||||||
|
} // flush_current
|
||||||
|
|
||||||
void flush_element()
|
void flush_element()
|
||||||
{
|
{
|
||||||
if((!pending_element_) || (pending_attribute_ != -1))
|
if((!pending_element_) || (pending_attribute_ != -1))
|
||||||
|
@ -307,6 +331,12 @@ private:
|
||||||
pending_element_ = false;
|
pending_element_ = false;
|
||||||
} // flush_element
|
} // flush_element
|
||||||
|
|
||||||
|
bool isCDATA()
|
||||||
|
{
|
||||||
|
QName currentElement = element_stack_.top();
|
||||||
|
return cdataElements_.find(currentElement) != cdataElements_.end();
|
||||||
|
} // isCDATA
|
||||||
|
|
||||||
void addNamespaceDeclarations()
|
void addNamespaceDeclarations()
|
||||||
{
|
{
|
||||||
for(NamespaceStack::Scope::const_iterator n = namespaceStack_.begin(), ne = namespaceStack_.end(); n != ne; ++n)
|
for(NamespaceStack::Scope::const_iterator n = namespaceStack_.begin(), ne = namespaceStack_.end(); n != ne; ++n)
|
||||||
|
@ -332,6 +362,8 @@ private:
|
||||||
int buffering_;
|
int buffering_;
|
||||||
bool pending_element_;
|
bool pending_element_;
|
||||||
int pending_attribute_;
|
int pending_attribute_;
|
||||||
|
bool pending_text_;
|
||||||
|
CDATAElements cdataElements_;
|
||||||
std::stack<QName> element_stack_;
|
std::stack<QName> element_stack_;
|
||||||
std::string target_;
|
std::string target_;
|
||||||
SAX::AttributesImpl<std::string, Arabica::default_string_adaptor<std::string> > atts_;
|
SAX::AttributesImpl<std::string, Arabica::default_string_adaptor<std::string> > atts_;
|
||||||
|
|
|
@ -51,8 +51,23 @@ struct QName
|
||||||
}
|
}
|
||||||
return QName(prefix, localName, namespaceURI);
|
return QName(prefix, localName, namespaceURI);
|
||||||
} // create
|
} // 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
|
}; // struct QName
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace XSLT
|
} // namespace XSLT
|
||||||
} // namespace Arabica
|
} // namespace Arabica
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -170,6 +170,18 @@ protected:
|
||||||
stream_ << ch;
|
stream_ << ch;
|
||||||
} // characters
|
} // 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)
|
void do_comment(const std::string& ch)
|
||||||
{
|
{
|
||||||
close_element_if_empty();
|
close_element_if_empty();
|
||||||
|
@ -335,6 +347,17 @@ protected:
|
||||||
lc.setNodeValue(lc.getNodeValue() + ch);
|
lc.setNodeValue(lc.getNodeValue() + ch);
|
||||||
} // do_characters
|
} // 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)
|
void do_comment(const std::string& ch)
|
||||||
{
|
{
|
||||||
current().appendChild(document().createComment(ch));
|
current().appendChild(document().createComment(ch));
|
||||||
|
|
Loading…
Add table
Reference in a new issue