mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
introduce XPath syntax to make handling configuration a bit easier
svn path=/trunk/; revision=11071
This commit is contained in:
parent
c8e0c372d9
commit
d3f70f50f0
7 changed files with 295 additions and 73 deletions
|
@ -159,9 +159,9 @@ TaskbarSettingsDlg::TaskbarSettingsDlg(HWND hwnd)
|
||||||
: super(hwnd),
|
: super(hwnd),
|
||||||
_cfg_org(g_Globals._cfg)
|
_cfg_org(g_Globals._cfg)
|
||||||
{
|
{
|
||||||
XMLPos options(g_Globals.get_cfg("desktopbar"), "options");
|
XMLPos options = g_Globals.get_cfg("desktopbar/options");
|
||||||
|
|
||||||
CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(options, "show-clock", true)? BST_CHECKED: BST_UNCHECKED);
|
CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(options, "show-clock", true)? BST_CHECKED: BST_UNCHECKED);
|
||||||
CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(options, "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED);
|
CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(options, "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,14 +192,14 @@ int TaskbarSettingsDlg::Command(int id, int code)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_SHOW_CLOCK: {
|
case ID_SHOW_CLOCK: {
|
||||||
XMLBoolRef boolRef1(XMLPos(g_Globals.get_cfg("desktopbar"),"options"), "show-clock", true);
|
XMLBoolRef boolRef1(XMLPos(g_Globals.get_cfg("desktopbar/options")), "show-clock", true);
|
||||||
boolRef1.toggle();
|
boolRef1.toggle();
|
||||||
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
|
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
|
||||||
PropSheet_Changed(GetParent(_hwnd), _hwnd);
|
PropSheet_Changed(GetParent(_hwnd), _hwnd);
|
||||||
break;}
|
break;}
|
||||||
|
|
||||||
case ID_HIDE_INACTIVE_ICONS: {
|
case ID_HIDE_INACTIVE_ICONS: {
|
||||||
XMLBoolRef boolRef2(XMLPos(g_Globals.get_cfg("notify-icons"),"options"), "hide-inactive", true);
|
XMLBoolRef boolRef2(XMLPos(g_Globals.get_cfg("notify-icons/options")), "hide-inactive", true);
|
||||||
boolRef2.toggle();
|
boolRef2.toggle();
|
||||||
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
|
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
|
||||||
PropSheet_Changed(GetParent(_hwnd), _hwnd);
|
PropSheet_Changed(GetParent(_hwnd), _hwnd);
|
||||||
|
@ -236,7 +236,7 @@ MdiSdiDlg::MdiSdiDlg(HWND hwnd)
|
||||||
{
|
{
|
||||||
CenterWindow(hwnd);
|
CenterWindow(hwnd);
|
||||||
|
|
||||||
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
|
XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
|
||||||
bool mdi = XMLBool(explorer_options, "mdi", true);
|
bool mdi = XMLBool(explorer_options, "mdi", true);
|
||||||
|
|
||||||
int id = mdi? IDC_MDI: IDC_SDI;
|
int id = mdi? IDC_MDI: IDC_SDI;
|
||||||
|
@ -250,7 +250,7 @@ int MdiSdiDlg::Command(int id, int code)
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case IDOK: {
|
case IDOK: {
|
||||||
bool mdi = IsDlgButtonChecked(_hwnd, IDC_MDI)==BST_CHECKED;
|
bool mdi = IsDlgButtonChecked(_hwnd, IDC_MDI)==BST_CHECKED;
|
||||||
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
|
XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
|
||||||
XMLBoolRef(explorer_options, "mdi") = mdi;
|
XMLBoolRef(explorer_options, "mdi") = mdi;
|
||||||
} // fall through
|
} // fall through
|
||||||
|
|
||||||
|
|
|
@ -113,21 +113,21 @@ void ExplorerGlobals::write_persistent()
|
||||||
|
|
||||||
XMLPos ExplorerGlobals::get_cfg()
|
XMLPos ExplorerGlobals::get_cfg()
|
||||||
{
|
{
|
||||||
XMLPos pos(&_cfg);
|
XMLPos cfg_pos(&_cfg);
|
||||||
|
|
||||||
pos.smart_create("explorer-cfg");
|
cfg_pos.smart_create("explorer-cfg");
|
||||||
|
|
||||||
return pos;
|
return cfg_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLPos ExplorerGlobals::get_cfg(const String& name)
|
XMLPos ExplorerGlobals::get_cfg(const char* path)
|
||||||
{
|
{
|
||||||
XMLPos pos(&_cfg);
|
XMLPos cfg_pos(&_cfg);
|
||||||
|
|
||||||
pos.smart_create("explorer-cfg");
|
cfg_pos.smart_create("explorer-cfg");
|
||||||
pos.smart_create(name);
|
cfg_pos.create_relative(path);
|
||||||
|
|
||||||
return pos;
|
return cfg_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine)
|
||||||
|
|
||||||
g_Globals._prescan_nodes = false;
|
g_Globals._prescan_nodes = false;
|
||||||
|
|
||||||
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
|
XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
|
||||||
XS_String mdiStr = XMLString(explorer_options, "mdi");
|
XS_String mdiStr = XMLString(explorer_options, "mdi");
|
||||||
|
|
||||||
if (mdiStr.empty())
|
if (mdiStr.empty())
|
||||||
|
|
|
@ -236,7 +236,7 @@ extern struct ExplorerGlobals
|
||||||
void write_persistent();
|
void write_persistent();
|
||||||
|
|
||||||
XMLPos get_cfg();
|
XMLPos get_cfg();
|
||||||
XMLPos get_cfg(const String& name);
|
XMLPos get_cfg(const char* path);
|
||||||
|
|
||||||
HINSTANCE _hInstance;
|
HINSTANCE _hInstance;
|
||||||
ATOM _hframeClass;
|
ATOM _hframeClass;
|
||||||
|
|
|
@ -112,7 +112,7 @@ int MainFrameBase::OpenShellFolders(LPIDA pida, HWND hFrameWnd)
|
||||||
} else {
|
} else {
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
#ifndef _NO_MDI
|
#ifndef _NO_MDI
|
||||||
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
|
XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
|
||||||
bool mdi = XMLBool(explorer_options, "mdi", true);
|
bool mdi = XMLBool(explorer_options, "mdi", true);
|
||||||
|
|
||||||
if (mdi)
|
if (mdi)
|
||||||
|
|
|
@ -209,25 +209,25 @@ void NotifyArea::read_config()
|
||||||
bool clock_visible = true;
|
bool clock_visible = true;
|
||||||
|
|
||||||
// read notification icon settings from XML configuration
|
// read notification icon settings from XML configuration
|
||||||
XMLPos pos = g_Globals.get_cfg();
|
XMLPos cfg_pos = g_Globals.get_cfg();
|
||||||
|
|
||||||
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
|
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
|
||||||
if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK))
|
if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (pos.go_down("desktopbar")) {
|
if (cfg_pos.go_down("desktopbar")) {
|
||||||
clock_visible = XMLBoolRef(XMLPos(pos,"options"), "show-clock", !get_hide_clock_from_registry());
|
clock_visible = XMLBoolRef(XMLPos(cfg_pos,"options"), "show-clock", !get_hide_clock_from_registry());
|
||||||
pos.back();
|
cfg_pos.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos.go_down("notify-icons")) {
|
if (cfg_pos.go_down("notify-icons")) {
|
||||||
XMLPos options(pos, "options");
|
XMLPos options(cfg_pos, "options");
|
||||||
|
|
||||||
_hide_inactive = XMLBool(options, "hide-inactive", true); ///@todo read default setting from registry
|
_hide_inactive = XMLBool(options, "hide-inactive", true); ///@todo read default setting from registry
|
||||||
_show_hidden = XMLBool(options, "show-hidden", false); ///@todo read default setting from registry
|
_show_hidden = XMLBool(options, "show-hidden", false); ///@todo read default setting from registry
|
||||||
|
|
||||||
XMLChildrenFilter icons(pos, "icon");
|
XMLChildrenFilter icons(cfg_pos, "icon");
|
||||||
|
|
||||||
for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) {
|
for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) {
|
||||||
const XMLNode& node = **it;
|
const XMLNode& node = **it;
|
||||||
|
@ -250,7 +250,7 @@ void NotifyArea::read_config()
|
||||||
_cfg.push_back(cfg);
|
_cfg.push_back(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.back();
|
cfg_pos.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
show_clock(clock_visible);
|
show_clock(clock_visible);
|
||||||
|
@ -259,16 +259,16 @@ void NotifyArea::read_config()
|
||||||
void NotifyArea::write_config()
|
void NotifyArea::write_config()
|
||||||
{
|
{
|
||||||
// write notification icon settings to XML configuration file
|
// write notification icon settings to XML configuration file
|
||||||
XMLPos pos = g_Globals.get_cfg();
|
XMLPos cfg_pos = g_Globals.get_cfg();
|
||||||
|
|
||||||
pos.smart_create("desktopbar");
|
cfg_pos.smart_create("desktopbar");
|
||||||
XMLBoolRef boolRef(XMLPos(pos,"options"), "show-clock");
|
XMLBoolRef boolRef(XMLPos(cfg_pos,"options"), "show-clock");
|
||||||
boolRef = _hwndClock!=0;
|
boolRef = _hwndClock!=0;
|
||||||
pos.back();
|
cfg_pos.back();
|
||||||
|
|
||||||
pos.smart_create("notify-icons");
|
cfg_pos.smart_create("notify-icons");
|
||||||
|
|
||||||
XMLPos options(pos, "options");
|
XMLPos options(cfg_pos, "options");
|
||||||
XMLBoolRef(options, "hide-inactive") = _hide_inactive;
|
XMLBoolRef(options, "hide-inactive") = _hide_inactive;
|
||||||
XMLBoolRef(options, "show-hidden") = _show_hidden;
|
XMLBoolRef(options, "show-hidden") = _show_hidden;
|
||||||
|
|
||||||
|
@ -276,21 +276,21 @@ void NotifyArea::write_config()
|
||||||
NotifyIconConfig& cfg = *it;
|
NotifyIconConfig& cfg = *it;
|
||||||
|
|
||||||
// search for the corresponding node using the original name
|
// search for the corresponding node using the original name
|
||||||
pos.smart_create("icon", "name", cfg._name);
|
cfg_pos.smart_create("icon", "name", cfg._name);
|
||||||
|
|
||||||
// refresh unique name
|
// refresh unique name
|
||||||
cfg.create_name();
|
cfg.create_name();
|
||||||
|
|
||||||
pos["name"] = cfg._name.c_str();
|
cfg_pos["name"] = cfg._name.c_str();
|
||||||
pos["text"] = cfg._tipText.c_str();
|
cfg_pos["text"] = cfg._tipText.c_str();
|
||||||
pos["window"] = cfg._windowTitle.c_str();
|
cfg_pos["window"] = cfg._windowTitle.c_str();
|
||||||
pos["module"] = cfg._modulePath.c_str();
|
cfg_pos["module"] = cfg._modulePath.c_str();
|
||||||
pos["show"] = string_from_mode(cfg._mode).c_str();
|
cfg_pos["show"] = string_from_mode(cfg._mode).c_str();
|
||||||
|
|
||||||
pos.back();
|
cfg_pos.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.back(); // smart_create
|
cfg_pos.back(); // smart_create
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyArea::show_clock(bool flag)
|
void NotifyArea::show_clock(bool flag)
|
||||||
|
@ -299,7 +299,7 @@ void NotifyArea::show_clock(bool flag)
|
||||||
|
|
||||||
if (vis != flag) {
|
if (vis != flag) {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
// smart_create clock window
|
// create clock window
|
||||||
_hwndClock = ClockWindow::Create(_hwnd);
|
_hwndClock = ClockWindow::Create(_hwnd);
|
||||||
|
|
||||||
if (_hwndClock) {
|
if (_hwndClock) {
|
||||||
|
|
|
@ -51,13 +51,211 @@ const LPCXSSTR XMLStorage::XS_NUMBERFMT = XS_TEXT("%d");
|
||||||
namespace XMLStorage {
|
namespace XMLStorage {
|
||||||
|
|
||||||
|
|
||||||
/// move X-Path like to position in XML tree
|
static std::string unescape(const char* s, char b='"', char e='"')
|
||||||
|
{
|
||||||
|
const char* end = s + strlen(s);
|
||||||
|
|
||||||
|
// if (*s == b)
|
||||||
|
// ++s;
|
||||||
|
//
|
||||||
|
// if (end>s && end[-1]==e)
|
||||||
|
// --end;
|
||||||
|
|
||||||
|
if (*s == b)
|
||||||
|
if (end>s && end[-1]==e)
|
||||||
|
++s, --end;
|
||||||
|
|
||||||
|
return std::string(s, end-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string unescape(const char* s, int l, char b='"', char e='"')
|
||||||
|
{
|
||||||
|
const char* end = s + l;
|
||||||
|
|
||||||
|
// if (*s == b)
|
||||||
|
// ++s;
|
||||||
|
//
|
||||||
|
// if (end>s && end[-1]==e)
|
||||||
|
// --end;
|
||||||
|
|
||||||
|
if (*s == b)
|
||||||
|
if (end>s && end[-1]==e)
|
||||||
|
++s, --end;
|
||||||
|
|
||||||
|
return std::string(s, end-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// move XPath like to position in XML tree
|
||||||
bool XMLPos::go(const char* path)
|
bool XMLPos::go(const char* path)
|
||||||
{
|
{
|
||||||
|
XMLNode* node = _cur;
|
||||||
|
|
||||||
///@todo
|
// Is this an absolute path?
|
||||||
|
if (*path == '/') {
|
||||||
|
node = _root;
|
||||||
|
++path;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
node = node->find_relative(path);
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
go_to(node);
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// move XPath like to position in XML tree
|
||||||
|
bool const_XMLPos::go(const char* path)
|
||||||
|
{
|
||||||
|
const XMLNode* node = _cur;
|
||||||
|
|
||||||
|
// Is this an absolute path?
|
||||||
|
if (*path == '/') {
|
||||||
|
node = _root;
|
||||||
|
++path;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node->find_relative(path);
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
go_to(node);
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const XMLNode* XMLNode::find_relative(const char* path) const
|
||||||
|
{
|
||||||
|
const XMLNode* node = this;
|
||||||
|
|
||||||
|
// parse relative path
|
||||||
|
while(*path) {
|
||||||
|
const char* slash = strchr(path, '/');
|
||||||
|
if (slash == path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int l = slash? slash-path: strlen(path);
|
||||||
|
std::string comp(path, l);
|
||||||
|
path += l;
|
||||||
|
|
||||||
|
// look for [n] and [@attr_name="attr_value"] expressions in path components
|
||||||
|
const char* bracket = strchr(comp.c_str(), '[');
|
||||||
|
l = bracket? bracket-comp.c_str(): comp.length();
|
||||||
|
std::string child_name(comp.c_str(), l);
|
||||||
|
std::string attr_name, attr_value;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
if (bracket) {
|
||||||
|
std::string expr = unescape(bracket, '[', ']');
|
||||||
|
const char* p = expr.c_str();
|
||||||
|
|
||||||
|
n = atoi(p); // read index number
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
n = n - 1; // convert into zero based index
|
||||||
|
|
||||||
|
const char* at = strchr(p, '@');
|
||||||
|
|
||||||
|
if (at) {
|
||||||
|
p = at + 1;
|
||||||
|
const char* equal = strchr(p, '=');
|
||||||
|
|
||||||
|
// read attribute name and value
|
||||||
|
if (equal) {
|
||||||
|
attr_name = unescape(p, equal-p);
|
||||||
|
attr_value = unescape(equal+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr_name.empty())
|
||||||
|
// search n.th child node with specified name
|
||||||
|
node = node->find(child_name, n);
|
||||||
|
else
|
||||||
|
// search n.th child node with specified name and matching attribute value
|
||||||
|
node = node->find(child_name, attr_name, attr_value, n);
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*path == '/')
|
||||||
|
++path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode* XMLNode::create_relative(const char* path)
|
||||||
|
{
|
||||||
|
XMLNode* node = this;
|
||||||
|
|
||||||
|
// parse relative path
|
||||||
|
while(*path) {
|
||||||
|
const char* slash = strchr(path, '/');
|
||||||
|
if (slash == path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int l = slash? slash-path: strlen(path);
|
||||||
|
std::string comp(path, l);
|
||||||
|
path += l;
|
||||||
|
|
||||||
|
// look for [n] and [@attr_name="attr_value"] expressions in path components
|
||||||
|
const char* bracket = strchr(comp.c_str(), '[');
|
||||||
|
l = bracket? bracket-comp.c_str(): comp.length();
|
||||||
|
std::string child_name(comp.c_str(), l);
|
||||||
|
std::string attr_name, attr_value;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
if (bracket) {
|
||||||
|
std::string expr = unescape(bracket, '[', ']');
|
||||||
|
const char* p = expr.c_str();
|
||||||
|
|
||||||
|
n = atoi(p); // read index number
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
n = n - 1; // convert into zero based index
|
||||||
|
|
||||||
|
const char* at = strchr(p, '@');
|
||||||
|
|
||||||
|
if (at) {
|
||||||
|
p = at + 1;
|
||||||
|
const char* equal = strchr(p, '=');
|
||||||
|
|
||||||
|
// read attribute name and value
|
||||||
|
if (equal) {
|
||||||
|
attr_name = unescape(p, equal-p);
|
||||||
|
attr_value = unescape(equal+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode* child;
|
||||||
|
|
||||||
|
if (attr_name.empty())
|
||||||
|
// search n.th child node with specified name
|
||||||
|
child = node->find(child_name, n);
|
||||||
|
else
|
||||||
|
// search n.th child node with specified name and matching attribute value
|
||||||
|
child = node->find(child_name, attr_name, attr_value, n);
|
||||||
|
|
||||||
|
if (!child) {
|
||||||
|
child = new XMLNode(child_name);
|
||||||
|
node->add_child(child);
|
||||||
|
|
||||||
|
if (!attr_name.empty())
|
||||||
|
(*node)[attr_name] = attr_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = child;
|
||||||
|
|
||||||
|
if (*path == '/')
|
||||||
|
++path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -511,9 +511,9 @@ struct XMLNode : public XS_String
|
||||||
}
|
}
|
||||||
|
|
||||||
/// convenient value access in children node
|
/// convenient value access in children node
|
||||||
XS_String subvalue(const XS_String& name, const XS_String& attr_name) const
|
XS_String subvalue(const XS_String& name, const XS_String& attr_name, int n=0) const
|
||||||
{
|
{
|
||||||
const XMLNode* node = find_first(name);
|
const XMLNode* node = find(name, n);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
return node->get(attr_name);
|
return node->get(attr_name);
|
||||||
|
@ -522,9 +522,9 @@ struct XMLNode : public XS_String
|
||||||
}
|
}
|
||||||
|
|
||||||
/// convenient storage of distinct values in children node
|
/// convenient storage of distinct values in children node
|
||||||
XS_String& subvalue(const XS_String& name, const XS_String& attr_name)
|
XS_String& subvalue(const XS_String& name, const XS_String& attr_name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = find_first(name);
|
XMLNode* node = find(name, n);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
node = new XMLNode(name);
|
node = new XMLNode(name);
|
||||||
|
@ -536,9 +536,9 @@ struct XMLNode : public XS_String
|
||||||
|
|
||||||
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
||||||
/// convenient value access in children node
|
/// convenient value access in children node
|
||||||
XS_String subvalue(const char* name, const char* attr_name) const
|
XS_String subvalue(const char* name, const char* attr_name, int n=0) const
|
||||||
{
|
{
|
||||||
const XMLNode* node = find_first(name);
|
const XMLNode* node = find(name, n);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
return node->get(attr_name);
|
return node->get(attr_name);
|
||||||
|
@ -547,9 +547,9 @@ struct XMLNode : public XS_String
|
||||||
}
|
}
|
||||||
|
|
||||||
/// convenient storage of distinct values in children node
|
/// convenient storage of distinct values in children node
|
||||||
XS_String& subvalue(const char* name, const XS_String& attr_name)
|
XS_String& subvalue(const char* name, const XS_String& attr_name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = find_first(name);
|
XMLNode* node = find(name, n);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
node = new XMLNode(name);
|
node = new XMLNode(name);
|
||||||
|
@ -629,51 +629,64 @@ protected:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode* find_first(const XS_String& name) const
|
XMLNode* find(const XS_String& name, int n=0) const
|
||||||
{
|
{
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||||
if (**it == name)
|
if (**it == name)
|
||||||
return *it;
|
if (!n--)
|
||||||
|
return *it;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode* find_first(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value) const
|
XMLNode* find(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value, int n=0) const
|
||||||
{
|
{
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
|
||||||
const XMLNode& node = **it;
|
const XMLNode& node = **it;
|
||||||
|
|
||||||
if (node==name && node.get(attr_name)==attr_value)
|
if (node==name && node.get(attr_name)==attr_value)
|
||||||
return *it;
|
if (!n--)
|
||||||
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
||||||
XMLNode* find_first(const char* name) const
|
XMLNode* find(const char* name, int n=0) const
|
||||||
{
|
{
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||||
if (**it == name)
|
if (**it == name)
|
||||||
return *it;
|
if (!n--)
|
||||||
|
return *it;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
XMLNode* find_first(const char* name, const T& attr_name, const U& attr_value) const
|
XMLNode* find(const char* name, const T& attr_name, const U& attr_value, int n=0) const
|
||||||
{
|
{
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
|
||||||
const XMLNode& node = **it;
|
const XMLNode& node = **it;
|
||||||
|
|
||||||
if (node==name && node.get(attr_name)==attr_value)
|
if (node==name && node.get(attr_name)==attr_value)
|
||||||
return *it;
|
if (!n--)
|
||||||
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// XPath find functions
|
||||||
|
const XMLNode* find_relative(const char* path) const;
|
||||||
|
|
||||||
|
XMLNode* find_relative(const char* path)
|
||||||
|
{return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->find_relative(path));}
|
||||||
|
|
||||||
|
/// relative XPath create function
|
||||||
|
XMLNode* create_relative(const char* path);
|
||||||
|
|
||||||
void write_worker(std::ostream& out, int indent) const;
|
void write_worker(std::ostream& out, int indent) const;
|
||||||
void pretty_write_worker(std::ostream& out, int indent) const;
|
void pretty_write_worker(std::ostream& out, int indent) const;
|
||||||
void smart_write_worker(std::ostream& out, int indent) const;
|
void smart_write_worker(std::ostream& out, int indent) const;
|
||||||
|
@ -981,9 +994,9 @@ struct XMLPos
|
||||||
}
|
}
|
||||||
|
|
||||||
/// search for child and go down
|
/// search for child and go down
|
||||||
bool go_down(const XS_String& name)
|
bool go_down(const XS_String& name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name, n);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -992,9 +1005,20 @@ struct XMLPos
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// move X-Path like to position in XML tree
|
/// move XPath like to position in XML tree
|
||||||
bool go(const char* path);
|
bool go(const char* path);
|
||||||
|
|
||||||
|
/// create child nodes using XPath notation and move to the deepest child
|
||||||
|
bool create_relative(const char* path)
|
||||||
|
{
|
||||||
|
XMLNode* node = _cur->create_relative(path);
|
||||||
|
if (!node)
|
||||||
|
return false; // invalid path specified
|
||||||
|
|
||||||
|
go_to(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// create node and move to it
|
/// create node and move to it
|
||||||
void create(const XS_String& name)
|
void create(const XS_String& name)
|
||||||
{
|
{
|
||||||
|
@ -1004,7 +1028,7 @@ struct XMLPos
|
||||||
/// create node if not already existing and move to it
|
/// create node if not already existing and move to it
|
||||||
void smart_create(const XS_String& name)
|
void smart_create(const XS_String& name)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1015,7 +1039,7 @@ struct XMLPos
|
||||||
/// search matching child node identified by key name and an attribute value
|
/// search matching child node identified by key name and an attribute value
|
||||||
void smart_create(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
|
void smart_create(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name, attr_name, attr_value);
|
XMLNode* node = _cur->find(name, attr_name, attr_value);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1028,9 +1052,9 @@ struct XMLPos
|
||||||
|
|
||||||
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
||||||
/// search for child and go down
|
/// search for child and go down
|
||||||
bool go_down(const char* name)
|
bool go_down(const char* name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name, n);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1048,7 +1072,7 @@ struct XMLPos
|
||||||
/// create node if not already existing and move to it
|
/// create node if not already existing and move to it
|
||||||
void smart_create(const char* name)
|
void smart_create(const char* name)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1060,7 +1084,7 @@ struct XMLPos
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void smart_create(const char* name, const T& attr_name, const U& attr_value)
|
void smart_create(const char* name, const T& attr_name, const U& attr_value)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name, attr_name, attr_value);
|
XMLNode* node = _cur->find(name, attr_name, attr_value);
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1150,9 +1174,9 @@ struct const_XMLPos
|
||||||
}
|
}
|
||||||
|
|
||||||
/// search for child and go down
|
/// search for child and go down
|
||||||
bool go_down(const XS_String& name)
|
bool go_down(const XS_String& name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name, n);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
@ -1161,14 +1185,14 @@ struct const_XMLPos
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// move X-Path like to position in XML tree
|
/// move XPath like to position in XML tree
|
||||||
bool go(const char* path);
|
bool go(const char* path);
|
||||||
|
|
||||||
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
|
||||||
/// search for child and go down
|
/// search for child and go down
|
||||||
bool go_down(const char* name)
|
bool go_down(const char* name, int n=0)
|
||||||
{
|
{
|
||||||
XMLNode* node = _cur->find_first(name);
|
XMLNode* node = _cur->find(name, n);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
go_to(node);
|
go_to(node);
|
||||||
|
|
Loading…
Reference in a new issue