xmlstorage.cpp
字号:
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (pos->_children.empty()) { // no children in last node?
if (pReader->_last_tag == TAG_START)
pos->_content.append(s, p-s);
else if (pReader->_last_tag == TAG_END)
pos->_trailing.append(s, p-s);
// else TAG_NONE -> don't store white space in root node
} else
pos->_children.back()->_trailing.append(s, p-s);
std::string leading;
if (p != e)
leading.assign(p, e-p);
XMLNode* node = new XMLNode(String_from_XML_Char(name), leading);
pos.add_down(node);
while(*atts) {
const XML_Char* attr_name = *atts++;
const XML_Char* attr_value = *atts++;
(*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
}
pReader->_last_tag = TAG_START;
pReader->_content.erase();
}
/// notifications about XML end tag
void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLPos& pos = pReader->_pos;
// search for end of first line
const char* s = pReader->_content.c_str();
const char* p = s;
const char* e = p + pReader->_content.length();
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 (pReader->_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();
pReader->_last_tag = TAG_END;
pReader->_content.erase();
}
/// store content, white space and comments
void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->_content.append(s, len);
}
std::string XMLReaderBase::get_error_string() const
{
XML_Error error = XML_GetErrorCode(_parser);
switch(error) {
case XML_ERROR_NONE: return "XML_ERROR_NONE";
case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY";
case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX";
case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS";
case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN";
case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN";
case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR";
case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH";
case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE";
case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF";
case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY";
case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF";
case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY";
case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF";
case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF";
case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI";
case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING";
case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING";
case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION";
case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE";
case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE";
case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE";
case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX";
// EXPAT version >= 1.95.8
#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7)
case XML_ERROR_UNDECLARING_PREFIX: return "XML_ERROR_UNDECLARING_PREFIX";
case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE";
case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL";
case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL";
case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID";
case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED";
case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED";
case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED";
case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED";
case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE";
//#endif
//#if XML_MAJOR_VERSION>=2
/* Added in 2.0. */
case XML_ERROR_RESERVED_PREFIX_XML: return "XML_ERROR_RESERVED_PREFIX_XML";
case XML_ERROR_RESERVED_PREFIX_XMLNS: return "XML_ERROR_RESERVED_PREFIX_XMLNS";
case XML_ERROR_RESERVED_NAMESPACE_URI: return "XML_ERROR_RESERVED_NAMESPACE_URI";
#endif
}
std::ostringstream out;
out << "XML parser error #" << error;
return out.str();
}
std::string EncodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(5*sizeof(XS_CHAR)*XS_len(s)); // worst case. "&"
LPXSSTR o = buffer;
for(LPCXSSTR p=s; *p; ++p)
switch(*p) {
case '&':
*o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';';
break;
case '<':
*o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';';
break;
case '>':
*o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';';
break;
case '"':
*o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';';
break;
case '\'':
*o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';';
break;
default:
*o++ = *p;
}
#ifdef XS_STRING_UTF8
return XS_String(buffer, o-buffer);
#else
return get_utf8(buffer, o-buffer);
#endif
}
XS_String DecodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
LPXSSTR o = buffer;
for(LPCXSSTR p=s; *p; ++p)
if (*p == '&') {
if (!XS_nicmp(p+1, XS_TEXT("lt;"), 3)) {
*o++ = '<';
p += 3;
} else if (!XS_nicmp(p+1, XS_TEXT("gt;"), 3)) {
*o++ = '>';
p += 3;
} else if (!XS_nicmp(p+1, XS_TEXT("amp;"), 4)) {
*o++ = '&';
p += 4;
} else if (!XS_nicmp(p+1, XS_TEXT("quot;"), 5)) {
*o++ = '"';
p += 5;
} else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
*o++ = '\'';
p += 5;
} 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;
}
/// pretty print node with children tree to output stream
void XMLNode::pretty_write_worker(std::ostream& out, 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 << ">\n";
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->pretty_write_worker(out, indent+1);
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
out << "</" << EncodeXMLString(*this) << ">\n";
} else
out << "/>\n";
}
/// write node with children tree to output stream using smart formating
void XMLNode::smart_write_worker(std::ostream& out, 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 << '\n';
else
out << _content;
Children::const_iterator it = _children.begin();
if (it != _children.end()) {
for(; it!=_children.end(); ++it)
(*it)->smart_write_worker(out, 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 << '\n';
else
out << _trailing;
}
} // namespace XMLStorage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -