mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
update XMLStorage: preserve CDATA formating of processed XML documents
svn path=/trunk/; revision=38492
This commit is contained in:
parent
ee252ea491
commit
607be3272e
3 changed files with 68 additions and 28 deletions
|
@ -471,9 +471,16 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// decode XML string literals
|
/// decode XML string literals
|
||||||
XS_String DecodeXMLString(const XS_String& str)
|
XS_String DecodeXMLString(const std::string& str)
|
||||||
{
|
{
|
||||||
LPCXSSTR s = str.c_str();
|
#ifdef XS_STRING_UTF8
|
||||||
|
const XS_String& str_utf8 = str;
|
||||||
|
#else
|
||||||
|
XS_String str_utf8;
|
||||||
|
assign_utf8(str_utf8, str.c_str(), str.length());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LPCXSSTR s = str_utf8.c_str();
|
||||||
LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
|
LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
|
||||||
LPXSSTR o = buffer;
|
LPXSSTR o = buffer;
|
||||||
|
|
||||||
|
@ -514,7 +521,7 @@ XS_String DecodeXMLString(const XS_String& str)
|
||||||
|
|
||||||
|
|
||||||
/// write node with children tree to output stream using original white space
|
/// write node with children tree to output stream using original white space
|
||||||
void XMLNode::write_worker(std::ostream& out) const
|
void XMLNode::original_write_worker(std::ostream& out) const
|
||||||
{
|
{
|
||||||
out << _leading << '<' << EncodeXMLString(*this);
|
out << _leading << '<' << EncodeXMLString(*this);
|
||||||
|
|
||||||
|
@ -522,10 +529,15 @@ void XMLNode::write_worker(std::ostream& out) const
|
||||||
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
|
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
|
||||||
|
|
||||||
if (!_children.empty() || !_content.empty()) {
|
if (!_children.empty() || !_content.empty()) {
|
||||||
out << '>' << _content;
|
out << '>';
|
||||||
|
|
||||||
|
if (_cdata_content)
|
||||||
|
out << EncodeXMLString(DecodeXMLString(_content), true);
|
||||||
|
else
|
||||||
|
out << _content;
|
||||||
|
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||||
(*it)->write_worker(out);
|
(*it)->original_write_worker(out);
|
||||||
|
|
||||||
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
|
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
|
||||||
} else
|
} else
|
||||||
|
@ -619,7 +631,9 @@ void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int
|
||||||
else {
|
else {
|
||||||
out << '>';
|
out << '>';
|
||||||
|
|
||||||
if (!*content)
|
if (_cdata_content)
|
||||||
|
out << EncodeXMLString(DecodeXMLString(_content), true);
|
||||||
|
else if (!*content)
|
||||||
out << format._endl;
|
out << format._endl;
|
||||||
else
|
else
|
||||||
out << content;
|
out << content;
|
||||||
|
@ -886,11 +900,15 @@ void XMLReaderBase::EndElementHandler()
|
||||||
if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
|
if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
|
||||||
s += 9;
|
s += 9;
|
||||||
p = (e-=3);
|
p = (e-=3);
|
||||||
|
|
||||||
|
_pos->_cdata_content = true;
|
||||||
} else {
|
} else {
|
||||||
// search for content end leaving only white space for _end_leading
|
// search for content end leaving only white space for _end_leading
|
||||||
for(p=e; p>s; --p)
|
for(p=e; p>s; --p)
|
||||||
if (!isspace((unsigned char)p[-1]))
|
if (!isspace((unsigned char)p[-1]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
_pos->_cdata_content = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p != s)
|
if (p != s)
|
||||||
|
|
|
@ -484,7 +484,7 @@ inline std::string get_utf8(const XS_String& s)
|
||||||
#endif // XS_STRING_UTF8
|
#endif // XS_STRING_UTF8
|
||||||
|
|
||||||
extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
|
extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
|
||||||
extern XS_String DecodeXMLString(const XS_String& str);
|
extern XS_String DecodeXMLString(const std::string& str);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -961,13 +961,15 @@ struct XMLNode : public XS_String
|
||||||
friend struct XPathElement;
|
friend struct XPathElement;
|
||||||
|
|
||||||
XMLNode(const XS_String& name)
|
XMLNode(const XS_String& name)
|
||||||
: XS_String(name)
|
: XS_String(name),
|
||||||
|
_cdata_content(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode(const XS_String& name, const std::string& leading)
|
XMLNode(const XS_String& name, const std::string& leading)
|
||||||
: XS_String(name),
|
: XS_String(name),
|
||||||
_leading(leading)
|
_leading(leading),
|
||||||
|
_cdata_content(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,10 +979,11 @@ struct XMLNode : public XS_String
|
||||||
_leading(other._leading),
|
_leading(other._leading),
|
||||||
_content(other._content),
|
_content(other._content),
|
||||||
_end_leading(other._end_leading),
|
_end_leading(other._end_leading),
|
||||||
_trailing(other._trailing)
|
_trailing(other._trailing),
|
||||||
#ifdef XMLNODE_LOCATION
|
#ifdef XMLNODE_LOCATION
|
||||||
, _location(other._location)
|
_location(other._location),
|
||||||
#endif
|
#endif
|
||||||
|
_cdata_content(false)
|
||||||
{
|
{
|
||||||
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
|
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
|
||||||
_children.push_back(new XMLNode(**it));
|
_children.push_back(new XMLNode(**it));
|
||||||
|
@ -994,10 +997,11 @@ struct XMLNode : public XS_String
|
||||||
_leading(other._leading),
|
_leading(other._leading),
|
||||||
_content(other._content),
|
_content(other._content),
|
||||||
_end_leading(other._end_leading),
|
_end_leading(other._end_leading),
|
||||||
_trailing(other._trailing)
|
_trailing(other._trailing),
|
||||||
#ifdef XMLNODE_LOCATION
|
#ifdef XMLNODE_LOCATION
|
||||||
, _location(other._location)
|
_location(other._location),
|
||||||
#endif
|
#endif
|
||||||
|
_cdata_content(false)
|
||||||
{
|
{
|
||||||
// assert(copy_no_children==COPY_NOCHILDREN);
|
// assert(copy_no_children==COPY_NOCHILDREN);
|
||||||
}
|
}
|
||||||
|
@ -1153,23 +1157,41 @@ struct XMLNode : public XS_String
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// read element node content
|
||||||
XS_String get_content() const
|
XS_String get_content() const
|
||||||
{
|
{
|
||||||
#ifdef XS_STRING_UTF8
|
return DecodeXMLString(_content);
|
||||||
const XS_String& ret = _content;
|
|
||||||
#else
|
|
||||||
XS_String ret;
|
|
||||||
assign_utf8(ret, _content.c_str(), _content.length());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return DecodeXMLString(ret.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// read content of a subnode specified by an XPath expression
|
||||||
|
XS_String get_sub_content(const XPath& xpath) const
|
||||||
|
{
|
||||||
|
const XMLNode* node = find_relative(xpath);
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
return node->get_content();
|
||||||
|
else
|
||||||
|
return XS_EMPTY_STR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set element node content
|
||||||
void set_content(const XS_String& s, bool cdata=false)
|
void set_content(const XS_String& s, bool cdata=false)
|
||||||
{
|
{
|
||||||
_content.assign(EncodeXMLString(s.c_str(), cdata));
|
_content.assign(EncodeXMLString(s.c_str(), cdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// set content of a subnode specified by an XPath expression
|
||||||
|
bool set_sub_content(const XPath& xpath, const XS_String& s, bool cdata=false)
|
||||||
|
{
|
||||||
|
XMLNode* node = find_relative(xpath);
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
node->set_content(s, cdata);
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef XMLNODE_LOCATION
|
#ifdef XMLNODE_LOCATION
|
||||||
const XMLLocation& get_location() const {return _location;}
|
const XMLLocation& get_location() const {return _location;}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1187,10 +1209,10 @@ struct XMLNode : public XS_String
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_ORIGINAL:
|
case FORMAT_ORIGINAL:
|
||||||
write_worker(out);
|
original_write_worker(out);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // FORMAT_SMART
|
default: // FORMAT_SMART
|
||||||
smart_write_worker(out, format, indent);
|
smart_write_worker(out, format, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,6 +1244,8 @@ protected:
|
||||||
XMLLocation _location;
|
XMLLocation _location;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool _cdata_content;
|
||||||
|
|
||||||
XMLNode* get_first_child() const
|
XMLNode* get_first_child() const
|
||||||
{
|
{
|
||||||
if (!_children.empty())
|
if (!_children.empty())
|
||||||
|
@ -1242,7 +1266,7 @@ protected:
|
||||||
/// create a new node tree using the given XPath filter expression
|
/// create a new node tree using the given XPath filter expression
|
||||||
XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const;
|
XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const;
|
||||||
|
|
||||||
void write_worker(std::ostream& out) const;
|
void original_write_worker(std::ostream& out) const;
|
||||||
void plain_write_worker(std::ostream& out) const;
|
void plain_write_worker(std::ostream& out) const;
|
||||||
void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
|
void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
|
||||||
void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
|
void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
|
||||||
|
|
|
@ -206,14 +206,12 @@ struct Buffer
|
||||||
|
|
||||||
#ifdef XS_STRING_UTF8
|
#ifdef XS_STRING_UTF8
|
||||||
XS_String name_str(attr_name, attr_len);
|
XS_String name_str(attr_name, attr_len);
|
||||||
XS_String value_str(value, value_len);
|
|
||||||
#else
|
#else
|
||||||
XS_String name_str, value_str;
|
XS_String name_str;
|
||||||
assign_utf8(name_str, attr_name, attr_len);
|
assign_utf8(name_str, attr_name, attr_len);
|
||||||
assign_utf8(value_str, value, value_len);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
attributes[name_str] = DecodeXMLString(value_str);
|
attributes[name_str] = DecodeXMLString(std::string(value, value_len));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue