📄 xmlstorage.cpp
字号:
p += 5;
} else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
*o++ = '\'';
p += 5;
} else
*o++ = *p;
} else if (*p=='<' && !XS_nicmp(p+1,XS_TEXT("![CDATA["),8)) {
LPCXSSTR e = XS_strstr(p+9, XS_TEXT("]]>"));
if (e) {
p += 9;
size_t l = e - p;
memcpy(o, p, l);
o += l;
p = e + 2;
} else
*o++ = *p;
} else
*o++ = *p;
return XS_String(buffer, o-buffer);
}
/// write node with children tree to output stream using original white space
void XMLNode::write_worker(std::ostream& out, int indent) const
{
out << _leading << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (!_children.empty() || !_content.empty()) {
out << '>' << _content;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->write_worker(out, indent+1);
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
} else
out << "/>";
out << _trailing;
}
/// print node without any white space
void XMLNode::plain_write_worker(std::ostream& out) const
{
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (!_children.empty()/*@@ || !_content.empty()*/) {
out << ">";
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->plain_write_worker(out);
out << "</" << EncodeXMLString(*this) << ">";
} else
out << "/>";
}
/// pretty print node with children tree to output stream
void XMLNode::pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const
{
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (!_children.empty()/*@@ || !_content.empty()*/) {
out << '>' << format._endl;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->pretty_write_worker(out, format, indent+1);
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
out << "</" << EncodeXMLString(*this) << '>' << format._endl;
} else
out << "/>" << format._endl;
}
/// write node with children tree to output stream using smart formating
void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const
{
if (_leading.empty())
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
out << _leading;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (_children.empty() && _content.empty())
out << "/>";
else {
out << '>';
if (_content.empty())
out << format._endl;
else
out << _content;
Children::const_iterator it = _children.begin();
if (it != _children.end()) {
for(; it!=_children.end(); ++it)
(*it)->smart_write_worker(out, format, indent+1);
if (_end_leading.empty())
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
out << _end_leading;
} else
out << _end_leading;
out << "</" << EncodeXMLString(*this) << '>';
}
if (_trailing.empty())
out << format._endl;
else
out << _trailing;
}
std::ostream& operator<<(std::ostream& out, const XMLError& err)
{
out << err._systemId << "(" << err._line << ") [column " << err._column << "] : "
<< err._message;
return out;
}
void DocType::parse(const char* p)
{
while(isspace((unsigned char)*p)) ++p;
const char* start = p;
while(isxmlsym(*p)) ++p;
_name.assign(start, p-start);
while(isspace((unsigned char)*p)) ++p;
start = p;
while(isxmlsym(*p)) ++p;
std::string keyword(p, p-start); // "PUBLIC" or "SYSTEM"
while(isspace((unsigned char)*p)) ++p;
if (*p=='"' || *p=='\'') {
char delim = *p;
start = ++p;
while(*p && *p!=delim) ++p;
if (*p == delim)
_public.assign(start, p++-start);
} else
_public.erase();
while(isspace((unsigned char)*p)) ++p;
if (*p=='"' || *p=='\'') {
char delim = *p;
start = ++p;
while(*p && *p!=delim) ++p;
if (*p == delim)
_system.assign(start, p++-start);
} else
_system.erase();
}
void XMLFormat::print_header(std::ostream& out, bool lf) const
{
out << "<?xml version=\"" << _version << "\" encoding=\"" << _encoding << "\"";
if (_standalone != -1)
out << " standalone=\"yes\"";
out << "?>";
if (lf)
out << _endl;
if (!_doctype.empty()) {
out << "<!DOCTYPE " << _doctype._name;
if (!_doctype._public.empty()) {
out << " PUBLIC \"" << _doctype._public << '"';
if (lf)
out << _endl;
out << " \"" << _doctype._system << '"';
} else if (!_doctype._system.empty())
out << " SYSTEM \"" << _doctype._system << '"';
out << "?>";
if (lf)
out << _endl;
}
for(StyleSheetList::const_iterator it=_stylesheets.begin(); it!=_stylesheets.end(); ++it) {
it->print(out);
if (lf)
out << _endl;
}
/* if (!_additional.empty()) {
out << _additional;
if (lf)
out << _endl;
} */
}
void StyleSheet::print(std::ostream& out) const
{
out << "<?xml-stylesheet"
" href=\"" << _href << "\""
" type=\"" << _type << "\"";
if (!_title.empty())
out << " title=\"" << _title << "\"";
if (!_media.empty())
out << " media=\"" << _media << "\"";
if (!_charset.empty())
out << " charset=\"" << _charset << "\"";
if (_alternate)
out << " alternate=\"yes\"";
out << "?>";
}
/// return formated error message
std::string XMLError::str() const
{
std::ostringstream out;
out << *this;
return out.str();
}
/// return merged error strings
XS_String XMLErrorList::str() const
{
std::ostringstream out;
for(const_iterator it=begin(); it!=end(); ++it)
out << *it << std::endl;
return out.str();
}
void XMLReaderBase::finish_read()
{
if (_pos->_children.empty())
_pos->_trailing.append(_content);
else
_pos->_children.back()->_trailing.append(_content);
_content.erase();
}
/// store XML version and encoding into XML reader
void XMLReaderBase::XmlDeclHandler(const char* version, const char* encoding, int standalone)
{
if (version)
_format._version = version;
if (encoding)
_format._encoding = encoding;
_format._standalone = standalone;
}
/// notifications about XML start tag
void XMLReaderBase::StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes)
{
// search for end of first line
const char* s = _content.c_str();
const char* p = s;
const char* e = p + _content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (_pos->_children.empty()) { // no children in last node?
if (_last_tag == TAG_START)
_pos->_content.append(s, p-s);
else if (_last_tag == TAG_END)
_pos->_trailing.append(s, p-s);
else // TAG_NONE at root node
p = s;
} else
_pos->_children.back()->_trailing.append(s, p-s);
std::string leading;
if (p != e)
leading.assign(p, e-p);
XMLNode* node = new XMLNode(name, leading);
_pos.add_down(node);
#ifdef XMLNODE_LOCATION
node->_location = get_location();
#endif
node->_attributes = attributes;
_last_tag = TAG_START;
_content.erase();
}
/// notifications about XML end tag
void XMLReaderBase::EndElementHandler()
{
// search for end of first line
const char* s = _content.c_str();
const char* p = s;
const char* e = p + _content.length();
if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
s += 9;
p = (e-=3);
} else
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (_pos->_children.empty()) // no children in current node?
_pos->_content.append(s, p-s);
else
if (_last_tag == TAG_START)
_pos->_content.append(s, p-s);
else
_pos->_children.back()->_trailing.append(s, p-s);
if (p != e)
_pos->_end_leading.assign(p, e-p);
_pos.back();
_last_tag = TAG_END;
_content.erase();
}
#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
/// store content, white space and comments
void XMLReaderBase::DefaultHandler(const XML_Char* s, int len)
{
#if defined(XML_UNICODE) || defined(XS_USE_XERCES)
_content.append(String_from_XML_Char(s, len));
#else
_content.append(s, len);
#endif
}
#endif
XS_String XMLWriter::s_empty_attr;
} // namespace XMLStorage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -