mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- XMLChildrenFilter iterator
- correctly encode special characters while writing XML strings - MIT license for XmlStorage classes svn path=/trunk/; revision=8890
This commit is contained in:
parent
287b32c870
commit
bf1b24c1fb
6 changed files with 437 additions and 161 deletions
|
@ -3,7 +3,7 @@
|
|||
<tr>
|
||||
<td><address style="align: right;"><small>
|
||||
ROS Explorer Source Code Documentation
|
||||
<br>generated on 22.03.2004 by <a href="http://www.doxygen.org/index.html">
|
||||
<br>generated on 27.03.2004 by <a href="http://www.doxygen.org/index.html">
|
||||
<img src="doxygen.png" alt="doxygen" align="middle" border=0>
|
||||
</small></address>
|
||||
</td>
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "utility/xmlstorage.h"
|
||||
|
||||
using namespace XMLStorage;
|
||||
|
||||
|
||||
/// management of file types
|
||||
struct FileTypeInfo {
|
||||
|
|
|
@ -195,11 +195,10 @@ void NotifyArea::read_config()
|
|||
|
||||
if (pos.go_down("explorer-cfg")) {
|
||||
if (pos.go_down("notify-icons")) {
|
||||
const XMLNode::Children& children = pos->get_children();
|
||||
XMLChildrenFilter icons(pos, "icon");
|
||||
|
||||
for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) {
|
||||
for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) {
|
||||
const XMLNode& node = **it;
|
||||
assert(node==TEXT("icon"));
|
||||
|
||||
NotifyIconConfig cfg;
|
||||
|
||||
|
|
|
@ -772,38 +772,6 @@ struct String
|
|||
operator wstring() const {WCHAR b[BUFFER_LEN]; return wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
|
||||
#endif
|
||||
|
||||
void assign_utf8(const char* str)
|
||||
{
|
||||
TCHAR buffer[BUFFER_LEN];
|
||||
|
||||
#ifdef UNICODE
|
||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, BUFFER_LEN) - 1;
|
||||
#else
|
||||
WCHAR wbuffer[BUFFER_LEN];
|
||||
|
||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuffer, BUFFER_LEN) - 1;
|
||||
l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||
#endif
|
||||
|
||||
assign(buffer, l);
|
||||
}
|
||||
|
||||
string get_utf8() const
|
||||
{
|
||||
char buffer[BUFFER_LEN];
|
||||
|
||||
#ifdef UNICODE
|
||||
int l = WideCharToMultiByte(CP_UTF8, 0, c_str(), length(), buffer, BUFFER_LEN, 0, 0);
|
||||
#else
|
||||
WCHAR wbuffer[BUFFER_LEN];
|
||||
|
||||
int l = MultiByteToWideChar(CP_ACP, 0, c_str(), length(), wbuffer, BUFFER_LEN);
|
||||
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||
#endif
|
||||
|
||||
return string(buffer, l);
|
||||
}
|
||||
|
||||
String& printf(LPCTSTR fmt, ...)
|
||||
{
|
||||
va_list l;
|
||||
|
@ -847,6 +815,8 @@ struct String
|
|||
}
|
||||
};
|
||||
|
||||
#define _STRING_DEFINED
|
||||
|
||||
|
||||
struct FmtString : public String
|
||||
{
|
||||
|
|
|
@ -1,50 +1,47 @@
|
|||
/*
|
||||
* Copyright 2004 Martin Fuchs
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// XML storage classes
|
||||
//
|
||||
// xmlstorage.cpp
|
||||
//
|
||||
// Martin Fuchs, 22.03.2004
|
||||
// Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
|
||||
//
|
||||
|
||||
|
||||
/*
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#include "xmlstorage.h"
|
||||
|
||||
|
||||
void xml_test() //@@
|
||||
{
|
||||
XMLDoc doc;
|
||||
|
||||
doc.read("explorer-cfg.xml");
|
||||
doc.write("out.xml");
|
||||
|
||||
XMLPos pos(&doc);
|
||||
|
||||
if (pos.go("\\explorer-cfg\\startmenu")) {
|
||||
|
||||
pos.back();
|
||||
}
|
||||
}
|
||||
namespace XMLStorage {
|
||||
|
||||
|
||||
/// move X-Path like to position in XML tree
|
||||
|
@ -107,3 +104,6 @@ void XMLCALL XMLReader::XML_DefaultHandler(void* userData, const XML_Char* s, in
|
|||
else
|
||||
pThis->_pos->append_trailing(s, len);
|
||||
}
|
||||
|
||||
|
||||
} // namespace XMLStorage
|
||||
|
|
|
@ -1,42 +1,234 @@
|
|||
/*
|
||||
* Copyright 2004 Martin Fuchs
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// XML storage classes
|
||||
//
|
||||
// xmlstorage.h
|
||||
//
|
||||
// Martin Fuchs, 22.03.2004
|
||||
// Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
|
||||
//
|
||||
|
||||
|
||||
#include "expat.h"
|
||||
/*
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "expat.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "libexpat.lib")
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
|
||||
#include <windows.h> // for LPCTSTR
|
||||
|
||||
#ifdef UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
#include <tchar.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
|
||||
#ifndef BUFFER_LEN
|
||||
#define BUFFER_LEN 2048
|
||||
#endif
|
||||
|
||||
|
||||
namespace XMLStorage {
|
||||
|
||||
|
||||
#ifndef _STRING_DEFINED
|
||||
|
||||
/// string class for TCHAR strings
|
||||
|
||||
struct String
|
||||
#ifdef UNICODE
|
||||
: public std::wstring
|
||||
#else
|
||||
: public std::string
|
||||
#endif
|
||||
{
|
||||
#ifdef UNICODE
|
||||
typedef std::wstring super;
|
||||
#else
|
||||
typedef std::string super;
|
||||
#endif
|
||||
|
||||
String() {}
|
||||
String(LPCTSTR s) {if (s) super::assign(s);}
|
||||
String(LPCTSTR s, int l) : super(s, l) {}
|
||||
String(const super& other) : super(other) {}
|
||||
String(const String& other) : super(other) {}
|
||||
|
||||
#ifdef UNICODE
|
||||
String(LPCSTR s) {assign(s);}
|
||||
String(LPCSTR s, int l) {assign(s, l);}
|
||||
String(const std::string& other) {assign(other.c_str());}
|
||||
String& operator=(LPCSTR s) {assign(s); return *this;}
|
||||
void assign(LPCSTR s) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);} else erase();}
|
||||
void assign(LPCSTR s, int l) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));} else erase();}
|
||||
#else
|
||||
String(LPCWSTR s) {assign(s);}
|
||||
String(LPCWSTR s, int l) {assign(s, l);}
|
||||
String(const std::wstring& other) {assign(other.c_str());}
|
||||
String& operator=(LPCWSTR s) {assign(s); return *this;}
|
||||
void assign(LPCWSTR s) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0)-1);} else erase();}
|
||||
void assign(LPCWSTR s, int l) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
|
||||
#endif
|
||||
|
||||
String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
|
||||
String& operator=(const super& s) {super::assign(s); return *this;}
|
||||
void assign(LPCTSTR s) {super::assign(s);}
|
||||
void assign(LPCTSTR s, int l) {super::assign(s, l);}
|
||||
|
||||
operator LPCTSTR() const {return c_str();}
|
||||
|
||||
#ifdef UNICODE
|
||||
operator std::string() const {char b[BUFFER_LEN]; return std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN, 0, 0)-1);}
|
||||
#else
|
||||
operator std::wstring() const {WCHAR b[BUFFER_LEN]; return std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
|
||||
#endif
|
||||
|
||||
String& printf(LPCTSTR fmt, ...)
|
||||
{
|
||||
va_list l;
|
||||
TCHAR b[BUFFER_LEN];
|
||||
|
||||
va_start(l, fmt);
|
||||
super::assign(b, _vstprintf(b, fmt, l));
|
||||
va_end(l);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& vprintf(LPCTSTR fmt, va_list l)
|
||||
{
|
||||
TCHAR b[BUFFER_LEN];
|
||||
|
||||
super::assign(b, _vstprintf(b, fmt, l));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& appendf(LPCTSTR fmt, ...)
|
||||
{
|
||||
va_list l;
|
||||
TCHAR b[BUFFER_LEN];
|
||||
|
||||
va_start(l, fmt);
|
||||
super::append(b, _vstprintf(b, fmt, l));
|
||||
va_end(l);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& vappendf(LPCTSTR fmt, va_list l)
|
||||
{
|
||||
TCHAR b[BUFFER_LEN];
|
||||
|
||||
super::append(b, _vstprintf(b, fmt, l));
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
inline void assign_utf8(String& s, const char* str)
|
||||
{
|
||||
TCHAR buffer[BUFFER_LEN];
|
||||
|
||||
#ifdef UNICODE
|
||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, BUFFER_LEN) - 1;
|
||||
#else
|
||||
WCHAR wbuffer[BUFFER_LEN];
|
||||
|
||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuffer, BUFFER_LEN) - 1;
|
||||
l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||
#endif
|
||||
|
||||
s.assign(buffer, l);
|
||||
}
|
||||
|
||||
inline std::string get_utf8(LPCTSTR s, int l)
|
||||
{
|
||||
char buffer[BUFFER_LEN];
|
||||
|
||||
#ifdef UNICODE
|
||||
l = WideCharToMultiByte(CP_UTF8, 0, s, l, buffer, BUFFER_LEN, 0, 0);
|
||||
#else
|
||||
WCHAR wbuffer[BUFFER_LEN];
|
||||
|
||||
l = MultiByteToWideChar(CP_ACP, 0, s, l, wbuffer, BUFFER_LEN);
|
||||
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||
#endif
|
||||
|
||||
return std::string(buffer, l);
|
||||
}
|
||||
|
||||
inline std::string get_utf8(const String& s)
|
||||
{
|
||||
return get_utf8(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
inline std::string XMLString(const String& s)
|
||||
{
|
||||
TCHAR buffer[BUFFER_LEN];
|
||||
LPTSTR o = buffer;
|
||||
|
||||
for(LPCTSTR 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;
|
||||
|
||||
default:
|
||||
*o++ = *p;
|
||||
}
|
||||
|
||||
return get_utf8(buffer, o-buffer);
|
||||
}
|
||||
|
||||
|
||||
// write XML files with 2 spaces indenting
|
||||
#define XML_INDENT_SPACE " "
|
||||
|
||||
|
@ -51,7 +243,7 @@ struct String_from_XML_Char : public String
|
|||
{
|
||||
String_from_XML_Char(const XML_Char* str)
|
||||
{
|
||||
assign_utf8(str);
|
||||
assign_utf8(*this, str);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -61,8 +253,12 @@ struct String_from_XML_Char : public String
|
|||
/// in memory representation of an XML node
|
||||
struct XMLNode : public String
|
||||
{
|
||||
typedef map<String, String> AttributeMap;
|
||||
typedef list<XMLNode*> Children;
|
||||
typedef std::map<String, String> AttributeMap;
|
||||
typedef std::list<XMLNode*> Children;
|
||||
|
||||
// access to protected class members for XMLPos anbd XMLReader
|
||||
friend struct XMLPos;
|
||||
friend struct XMLReader;
|
||||
|
||||
XMLNode(const String& name)
|
||||
: String(name)
|
||||
|
@ -105,6 +301,68 @@ struct XMLNode : public String
|
|||
return _children;
|
||||
}
|
||||
|
||||
Children& get_children()
|
||||
{
|
||||
return _children;
|
||||
}
|
||||
|
||||
/// write XML stream preserving original white space and comments
|
||||
std::ostream& write(std::ostream& out)
|
||||
{
|
||||
out << "<" << XMLString(*this);
|
||||
|
||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||
out << " " << XMLString(it->first) << "=\"" << XMLString(it->second) << "\"";
|
||||
|
||||
if (!_children.empty() || !_content.empty()) {
|
||||
out << ">" << _content;
|
||||
|
||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||
(*it)->write(out);
|
||||
|
||||
out << "</" << XMLString(*this) << ">" << _trailing;
|
||||
} else {
|
||||
out << "/>" << _trailing;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/// print write node to stream without preserving original white space
|
||||
std::ostream& write_formating(std::ostream& out, int indent=0)
|
||||
{
|
||||
for(int i=indent; i--; )
|
||||
out << XML_INDENT_SPACE;
|
||||
|
||||
out << "<" << XMLString(*this);
|
||||
|
||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||
out << " " << XMLString(it->first) << "=\"" << XMLString(it->second) << "\"";
|
||||
|
||||
if (!_children.empty()) {
|
||||
out << ">\n";
|
||||
|
||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||
(*it)->write_formating(out, indent+1);
|
||||
|
||||
for(int i=indent; i--; )
|
||||
out << XML_INDENT_SPACE;
|
||||
|
||||
out << "</" << XMLString(*this) << ">\n";
|
||||
} else {
|
||||
out << "/>\n";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
protected:
|
||||
Children _children;
|
||||
AttributeMap _attributes;
|
||||
|
||||
std::string _content;
|
||||
std::string _trailing;
|
||||
|
||||
XMLNode* get_first_child() const
|
||||
{
|
||||
if (!_children.empty())
|
||||
|
@ -149,63 +407,104 @@ struct XMLNode : public String
|
|||
else
|
||||
_children.back()->_trailing.append(s, l);
|
||||
}
|
||||
};
|
||||
|
||||
/// write XML stream preserving original white space and comments
|
||||
ostream& write(ostream& out)
|
||||
|
||||
/// iterator access to children nodes with name filtering
|
||||
struct XMLChildrenFilter
|
||||
{
|
||||
XMLChildrenFilter(XMLNode::Children& children, const String& name)
|
||||
: _begin(children.begin(), children.end(), name),
|
||||
_end(children.end(), children.end(), name)
|
||||
{
|
||||
out << "<" << get_utf8();
|
||||
|
||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||
out << " " << it->first.get_utf8() << "=\"" << it->second.get_utf8() << "\"";
|
||||
|
||||
if (!_children.empty() || !_content.empty()) {
|
||||
out << ">" << _content;
|
||||
|
||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||
(*it)->write(out);
|
||||
|
||||
out << "</" << get_utf8() << ">" << _trailing;
|
||||
} else {
|
||||
out << "/>" << _trailing;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/// print write node to stream without preserving original white space
|
||||
ostream& write_formating(ostream& out, int indent=0)
|
||||
XMLChildrenFilter(XMLNode* node, const String& name)
|
||||
: _begin(node->get_children().begin(), node->get_children().end(), name),
|
||||
_end(node->get_children().end(), node->get_children().end(), name)
|
||||
{
|
||||
for(int i=indent; i--; )
|
||||
out << XML_INDENT_SPACE;
|
||||
}
|
||||
|
||||
out << "<" << get_utf8();
|
||||
struct iterator
|
||||
{
|
||||
typedef XMLNode::Children::iterator BaseIterator;
|
||||
|
||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||
out << " " << it->first.get_utf8() << "=\"" << it->second.get_utf8() << "\"";
|
||||
|
||||
if (!_children.empty()) {
|
||||
out << ">\n";
|
||||
|
||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||
(*it)->write_formating(out, indent+1);
|
||||
|
||||
for(int i=indent; i--; )
|
||||
out << XML_INDENT_SPACE;
|
||||
|
||||
out << "</" << get_utf8() << ">\n";
|
||||
} else {
|
||||
out << "/>\n";
|
||||
iterator(BaseIterator begin, BaseIterator end, const String& filter_name)
|
||||
: _cur(begin),
|
||||
_end(end),
|
||||
_filter_name(filter_name)
|
||||
{
|
||||
search_next();
|
||||
}
|
||||
|
||||
return out;
|
||||
operator BaseIterator()
|
||||
{
|
||||
return _cur;
|
||||
}
|
||||
|
||||
const XMLNode* operator*() const
|
||||
{
|
||||
return *_cur;
|
||||
}
|
||||
|
||||
XMLNode* operator*()
|
||||
{
|
||||
return *_cur;
|
||||
}
|
||||
|
||||
iterator& operator++()
|
||||
{
|
||||
++_cur;
|
||||
search_next();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator ret = *this;
|
||||
|
||||
++_cur;
|
||||
search_next();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator==(const BaseIterator& other) const
|
||||
{
|
||||
return _cur == other;
|
||||
}
|
||||
|
||||
bool operator!=(const BaseIterator& other) const
|
||||
{
|
||||
return _cur != other;
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseIterator _cur;
|
||||
BaseIterator _end;
|
||||
String _filter_name;
|
||||
|
||||
void search_next()
|
||||
{
|
||||
while(_cur!=_end && **_cur!=_filter_name)
|
||||
++_cur;
|
||||
}
|
||||
};
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return _begin;
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return _end;
|
||||
}
|
||||
|
||||
protected:
|
||||
Children _children;
|
||||
AttributeMap _attributes;
|
||||
|
||||
string _content;
|
||||
string _trailing;
|
||||
iterator _begin;
|
||||
iterator _end;
|
||||
};
|
||||
|
||||
|
||||
|
@ -219,11 +518,14 @@ struct XMLPos
|
|||
}
|
||||
|
||||
/// access to current node
|
||||
XMLNode* operator->() {return _cur;}
|
||||
const XMLNode* operator->() const {return _cur;}
|
||||
operator XMLNode*() {return _cur;}
|
||||
operator const XMLNode*() const {return _cur;}
|
||||
|
||||
const XMLNode* operator->() const {return _cur;}
|
||||
XMLNode* operator->() {return _cur;}
|
||||
|
||||
XMLNode& operator*() {return *_cur;}
|
||||
const XMLNode& operator*() const {return *_cur;}
|
||||
XMLNode& operator*() {return *_cur;}
|
||||
|
||||
/// attribute access
|
||||
String& operator[](const String& attr_name) {return (*_cur)[attr_name];}
|
||||
|
@ -301,7 +603,7 @@ struct XMLPos
|
|||
protected:
|
||||
XMLNode* _root;
|
||||
XMLNode* _cur;
|
||||
stack<XMLNode*> _stack;
|
||||
std::stack<XMLNode*> _stack;
|
||||
|
||||
/// go to specified node
|
||||
void go_to(XMLNode* child)
|
||||
|
@ -336,7 +638,7 @@ struct XMLReader
|
|||
XML_ParserFree(_parser);
|
||||
}
|
||||
|
||||
XML_Status read(istream& in)
|
||||
XML_Status read(std::istream& in)
|
||||
{
|
||||
XML_Status status = XML_STATUS_OK;
|
||||
|
||||
|
@ -359,22 +661,22 @@ struct XMLReader
|
|||
return status;
|
||||
}
|
||||
|
||||
string get_position() const
|
||||
std::string get_position() const
|
||||
{
|
||||
int line = XML_GetCurrentLineNumber(_parser);
|
||||
int column = XML_GetCurrentColumnNumber(_parser);
|
||||
|
||||
ostringstream out;
|
||||
std::ostringstream out;
|
||||
out << "(" << line << ") : [column " << column << "]";
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
string get_error_string() const
|
||||
std::string get_error_string() const
|
||||
{
|
||||
XML_Error error = XML_GetErrorCode(_parser);
|
||||
|
||||
ostringstream out;
|
||||
std::ostringstream out;
|
||||
out << get_position() << " XML parser error #" << error << "\n";
|
||||
|
||||
return out.str();
|
||||
|
@ -383,8 +685,8 @@ struct XMLReader
|
|||
protected:
|
||||
XMLPos _pos;
|
||||
XML_Parser _parser;
|
||||
string _xml_version;
|
||||
string _encoding;
|
||||
std::string _xml_version;
|
||||
std::string _encoding;
|
||||
bool _in_tag;
|
||||
|
||||
static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone);
|
||||
|
@ -401,28 +703,28 @@ struct XMLDoc : public XMLNode
|
|||
{
|
||||
}
|
||||
|
||||
XMLDoc(const string& path)
|
||||
XMLDoc(const std::string& path)
|
||||
: XMLNode("")
|
||||
{
|
||||
read(path);
|
||||
}
|
||||
|
||||
istream& read(istream& in)
|
||||
std::istream& read(std::istream& in)
|
||||
{
|
||||
XMLReader(this).read(in);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
bool read(const string& path)
|
||||
bool read(const std::string& path)
|
||||
{
|
||||
ifstream in(path.c_str());
|
||||
std::ifstream in(path.c_str());
|
||||
|
||||
return XMLReader(this).read(in) != XML_STATUS_ERROR;
|
||||
}
|
||||
|
||||
/// write XML stream preserving previous white space and comments
|
||||
ostream& write(ostream& out, const string& xml_version="1.0", const string& encoding="UTF-8")
|
||||
std::ostream& write(std::ostream& out, const std::string& xml_version="1.0", const std::string& encoding="UTF-8")
|
||||
{
|
||||
out << "<?xml version=\"" << xml_version << "\" encoding=\"" << encoding << "\"?>\n";
|
||||
|
||||
|
@ -433,7 +735,7 @@ struct XMLDoc : public XMLNode
|
|||
}
|
||||
|
||||
/// write XML stream with formating
|
||||
ostream& write_formating(ostream& out)
|
||||
std::ostream& write_formating(std::ostream& out)
|
||||
{
|
||||
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
|
||||
|
@ -443,17 +745,20 @@ struct XMLDoc : public XMLNode
|
|||
return out;
|
||||
}
|
||||
|
||||
void write(const string& path, const string& xml_version="1.0", const string& encoding="UTF-8")
|
||||
void write(const std::string& path, const std::string& xml_version="1.0", const std::string& encoding="UTF-8")
|
||||
{
|
||||
ofstream out(path.c_str());
|
||||
std::ofstream out(path.c_str());
|
||||
|
||||
write(out, xml_version);
|
||||
}
|
||||
|
||||
void write_formating(const string& path)
|
||||
void write_formating(const std::string& path)
|
||||
{
|
||||
ofstream out(path.c_str());
|
||||
std::ofstream out(path.c_str());
|
||||
|
||||
write_formating(out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace XMLStorage
|
||||
|
|
Loading…
Reference in a new issue