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
|
||||
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 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
|
||||
void XMLNode::write_worker(std::ostream& out) const
|
||||
void XMLNode::original_write_worker(std::ostream& out) const
|
||||
{
|
||||
out << _leading << '<' << EncodeXMLString(*this);
|
||||
|
||||
|
@ -522,10 +529,15 @@ void XMLNode::write_worker(std::ostream& out) const
|
|||
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
|
||||
|
||||
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)
|
||||
(*it)->write_worker(out);
|
||||
(*it)->original_write_worker(out);
|
||||
|
||||
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
|
||||
} else
|
||||
|
@ -619,7 +631,9 @@ void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int
|
|||
else {
|
||||
out << '>';
|
||||
|
||||
if (!*content)
|
||||
if (_cdata_content)
|
||||
out << EncodeXMLString(DecodeXMLString(_content), true);
|
||||
else if (!*content)
|
||||
out << format._endl;
|
||||
else
|
||||
out << content;
|
||||
|
@ -886,11 +900,15 @@ void XMLReaderBase::EndElementHandler()
|
|||
if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
|
||||
s += 9;
|
||||
p = (e-=3);
|
||||
|
||||
_pos->_cdata_content = true;
|
||||
} else {
|
||||
// search for content end leaving only white space for _end_leading
|
||||
for(p=e; p>s; --p)
|
||||
if (!isspace((unsigned char)p[-1]))
|
||||
break;
|
||||
|
||||
_pos->_cdata_content = false;
|
||||
}
|
||||
|
||||
if (p != s)
|
||||
|
|
|
@ -484,7 +484,7 @@ inline std::string get_utf8(const XS_String& s)
|
|||
#endif // XS_STRING_UTF8
|
||||
|
||||
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__
|
||||
|
@ -961,13 +961,15 @@ struct XMLNode : public XS_String
|
|||
friend struct XPathElement;
|
||||
|
||||
XMLNode(const XS_String& name)
|
||||
: XS_String(name)
|
||||
: XS_String(name),
|
||||
_cdata_content(false)
|
||||
{
|
||||
}
|
||||
|
||||
XMLNode(const XS_String& name, const std::string& leading)
|
||||
: XS_String(name),
|
||||
_leading(leading)
|
||||
_leading(leading),
|
||||
_cdata_content(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -977,10 +979,11 @@ struct XMLNode : public XS_String
|
|||
_leading(other._leading),
|
||||
_content(other._content),
|
||||
_end_leading(other._end_leading),
|
||||
_trailing(other._trailing)
|
||||
_trailing(other._trailing),
|
||||
#ifdef XMLNODE_LOCATION
|
||||
, _location(other._location)
|
||||
_location(other._location),
|
||||
#endif
|
||||
_cdata_content(false)
|
||||
{
|
||||
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
|
||||
_children.push_back(new XMLNode(**it));
|
||||
|
@ -994,10 +997,11 @@ struct XMLNode : public XS_String
|
|||
_leading(other._leading),
|
||||
_content(other._content),
|
||||
_end_leading(other._end_leading),
|
||||
_trailing(other._trailing)
|
||||
_trailing(other._trailing),
|
||||
#ifdef XMLNODE_LOCATION
|
||||
, _location(other._location)
|
||||
_location(other._location),
|
||||
#endif
|
||||
_cdata_content(false)
|
||||
{
|
||||
// assert(copy_no_children==COPY_NOCHILDREN);
|
||||
}
|
||||
|
@ -1153,23 +1157,41 @@ struct XMLNode : public XS_String
|
|||
return _attributes;
|
||||
}
|
||||
|
||||
/// read element node content
|
||||
XS_String get_content() const
|
||||
{
|
||||
#ifdef XS_STRING_UTF8
|
||||
const XS_String& ret = _content;
|
||||
#else
|
||||
XS_String ret;
|
||||
assign_utf8(ret, _content.c_str(), _content.length());
|
||||
#endif
|
||||
|
||||
return DecodeXMLString(ret.c_str());
|
||||
return DecodeXMLString(_content);
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
_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
|
||||
const XMLLocation& get_location() const {return _location;}
|
||||
#endif
|
||||
|
@ -1187,7 +1209,7 @@ struct XMLNode : public XS_String
|
|||
break;
|
||||
|
||||
case FORMAT_ORIGINAL:
|
||||
write_worker(out);
|
||||
original_write_worker(out);
|
||||
break;
|
||||
|
||||
default: // FORMAT_SMART
|
||||
|
@ -1222,6 +1244,8 @@ protected:
|
|||
XMLLocation _location;
|
||||
#endif
|
||||
|
||||
bool _cdata_content;
|
||||
|
||||
XMLNode* get_first_child() const
|
||||
{
|
||||
if (!_children.empty())
|
||||
|
@ -1242,7 +1266,7 @@ protected:
|
|||
/// create a new node tree using the given XPath filter expression
|
||||
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 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;
|
||||
|
|
|
@ -206,14 +206,12 @@ struct Buffer
|
|||
|
||||
#ifdef XS_STRING_UTF8
|
||||
XS_String name_str(attr_name, attr_len);
|
||||
XS_String value_str(value, value_len);
|
||||
#else
|
||||
XS_String name_str, value_str;
|
||||
XS_String name_str;
|
||||
assign_utf8(name_str, attr_name, attr_len);
|
||||
assign_utf8(value_str, value, value_len);
|
||||
#endif
|
||||
|
||||
attributes[name_str] = DecodeXMLString(value_str);
|
||||
attributes[name_str] = DecodeXMLString(std::string(value, value_len));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue