Commit ee93be67 authored by Pavel Vainerman's avatar Pavel Vainerman

Merge branch 'unixml_iterator' into v1.0_prepare

parents e0efd2da 910b4860
......@@ -38,85 +38,8 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
class UniXML
{
public:
inline xmlNode* getFirstNode()
{
return xmlDocGetRootElement(doc);
}
// Загружает указанный файл
void open(const std::string filename);
void close();
inline bool isOpen(){ return doc!=0; }
UniXML(const std::string filename);
UniXML();
~UniXML();
xmlNode* cur;
xmlDoc* doc;
std::string filename;
// Создать новый XML-документ
void newDoc(const std::string& root_node, std::string xml_ver="1.0");
// Получить свойство name указанного узла node
static std::string getProp(const xmlNode* node, const std::string name);
static std::string getPropUtf8(const xmlNode* node, const std::string name);
static int getIntProp(const xmlNode* node, const std::string name);
/// if value if not positive ( <= 0 ), returns def
static int getPIntProp(const xmlNode* node, const std::string name, int def);
// Установить свойство name указанного узла node
static void setProp(xmlNode* node, const std::string name, const std::string text);
// Добавить новый дочерний узел
static xmlNode* createChild(xmlNode* node, const std::string title, const std::string text);
// Добавить следующий узел
static xmlNode* createNext(xmlNode* node, const std::string title, const std::string text);
// Удалить указанный узел и все вложенные узлы
static void removeNode(xmlNode* node);
// Удалить указанный узел и все вложенные узлы
static xmlNode* copyNode(xmlNode* node, int recursive=1);
// Сохранить в файл, если параметр не указан, сохраняет в тот файл
// который был загружен последним.
bool save(const std::string filename="", int level = 2);
// Переместить указатель к следующему узлу
static xmlNode* nextNode(xmlNode* node);
// После проверки исправить рекурсивный алгоритм на обычный,
// используя ->parent
xmlNode* findNode(xmlNode* node, const std::string searchnode, const std::string name = "") const;
xmlNode* findNodeUtf8(xmlNode* node, const std::string searchnode, const std::string name = "") const;
xmlNode* extFindNode(xmlNode* node, int depth, int width, const std::string searchnode, const std::string name = "", bool top=true );
xmlNode* extFindNodeUtf8(xmlNode* node, int depth, int width, const std::string searchnode, const std::string name = "", bool top=true );
protected:
// Преобразование текстовой строки из XML в строку нашего внутреннего представления
static std::string xml2local(const std::string text);
// Преобразование текстовой строки из нашего внутреннего представления в строку для XML
// Возвращает указатель на временный буфер, который один на все вызовы функции.
static const xmlChar* local2xml(std::string text);
static std::string local2utf8(const std::string text);
static int recur;
};
class UniXML_iterator
class UniXML_iterator : public std::iterator<std::bidirectional_iterator_tag, xmlNode, ptrdiff_t, xmlNode*, xmlNode&>
{
public:
UniXML_iterator(xmlNode* node) :
......@@ -131,6 +54,9 @@ class UniXML_iterator
int getPIntProp(const std::string name, int def) const;
void setProp(const std::string name, const std::string text);
bool findName(const std::string node, const std::string searchname);
bool find(const std::string searchnode);
/*! Перейти к следующему узлу. Возвращает false, если некуда перейти */
bool goNext();
......@@ -144,16 +70,12 @@ class UniXML_iterator
bool canNext();
// Перейти к следующему узлу
void operator ++()
{
goNext();
}
UniXML_iterator operator ++(int);
UniXML_iterator operator ++();
// Перейти к предыдущему узлу
void operator --()
{
goPrev();
}
UniXML_iterator operator --(int);
UniXML_iterator operator --();
/*! Перейти на один уровень выше
\note Если перейти не удалось, итератор остаётся указывать на прежний узел
......@@ -198,9 +120,99 @@ class UniXML_iterator
while(canNext()){goNext();}
}
private:
protected:
xmlNode* curNode;
};
class UniXML
{
public:
typedef UniXML_iterator iterator;
inline xmlNode* getFirstNode()
{
return xmlDocGetRootElement(doc);
}
/*! возвращает итератор на самый первый узел документа */
inline iterator begin()
{
return iterator(getFirstNode());
}
inline iterator end()
{
return iterator(NULL);
}
// Загружает указанный файл
void open(const std::string filename);
void close();
inline bool isOpen(){ return doc!=0; }
UniXML(const std::string filename);
UniXML();
~UniXML();
xmlNode* cur;
xmlDoc* doc;
std::string filename;
// Создать новый XML-документ
void newDoc(const std::string& root_node, std::string xml_ver="1.0");
// Получить свойство name указанного узла node
static std::string getProp(const xmlNode* node, const std::string name);
static std::string getPropUtf8(const xmlNode* node, const std::string name);
static int getIntProp(const xmlNode* node, const std::string name);
/// if value if not positive ( <= 0 ), returns def
static int getPIntProp(const xmlNode* node, const std::string name, int def);
// Установить свойство name указанного узла node
static void setProp(xmlNode* node, const std::string name, const std::string text);
// Добавить новый дочерний узел
static xmlNode* createChild(xmlNode* node, const std::string title, const std::string text);
// Добавить следующий узел
static xmlNode* createNext(xmlNode* node, const std::string title, const std::string text);
// Удалить указанный узел и все вложенные узлы
static void removeNode(xmlNode* node);
// Удалить указанный узел и все вложенные узлы
static xmlNode* copyNode(xmlNode* node, int recursive=1);
// Сохранить в файл, если параметр не указан, сохраняет в тот файл
// который был загружен последним.
bool save(const std::string filename="", int level = 2);
// Переместить указатель к следующему узлу
static xmlNode* nextNode(xmlNode* node);
// После проверки исправить рекурсивный алгоритм на обычный,
// используя ->parent
xmlNode* findNode(xmlNode* node, const std::string searchnode, const std::string name = "") const;
xmlNode* findNodeUtf8(xmlNode* node, const std::string searchnode, const std::string name = "") const;
xmlNode* extFindNode(xmlNode* node, int depth, int width, const std::string searchnode, const std::string name = "", bool top=true );
xmlNode* extFindNodeUtf8(xmlNode* node, int depth, int width, const std::string searchnode, const std::string name = "", bool top=true );
protected:
// Преобразование текстовой строки из XML в строку нашего внутреннего представления
static std::string xml2local(const std::string text);
// Преобразование текстовой строки из нашего внутреннего представления в строку для XML
// Возвращает указатель на временный буфер, который один на все вызовы функции.
static const xmlChar* local2xml(std::string text);
static std::string local2utf8(const std::string text);
static int recur;
};
#endif
......@@ -416,4 +416,131 @@ void UniXML_iterator::setProp( const string name, const string text )
{
UniXML::setProp(curNode, name, text);
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
bool UniXML_iterator::findName( const std::string node, const std::string searchname )
{
while( find(node) )
{
if ( searchname == getProp("name") )
return true;
}
return false;
}
// -------------------------------------------------------------------------
bool UniXML_iterator::find( const std::string searchnode )
{
while (curNode != NULL)
{
while( curNode->children )
{
curNode=curNode->children;
if ( searchnode == (const char*)curNode->name )
return true;
}
while(!curNode->next && curNode->parent)
{
curNode=curNode->parent;
}
curNode=curNode->next;
if ( curNode && searchnode == (const char*)curNode->name )
{
return true;
}
}
return false;
}
// -------------------------------------------------------------------------
UniXML_iterator UniXML_iterator::operator++()
{
if (!curNode->next)
{
curNode=curNode->next;
return *this;
}
for(;;)
{
curNode=curNode->next;
if (getName() == "text" || getName() == "comment")
continue;
else
break;
}
return *this;
}
UniXML_iterator UniXML_iterator::operator++(int)
{
UniXML_iterator it = *this;
if (!curNode->next)
{
curNode=curNode->next;
return it;
}
for(;;)
{
curNode=curNode->next;
if (getName() == "text" || getName() == "comment")
continue;
else
break;
}
return it;
}
// -------------------------------------------------------------------------
UniXML_iterator UniXML_iterator::operator--()
{
if (!curNode->prev)
{
curNode=curNode->prev;
return *this;
}
for(;;)
{
curNode=curNode->prev;
if (getName() == "text" || getName() == "comment")
continue;
else
break;
}
return *this;
}
UniXML_iterator UniXML_iterator::operator--(int)
{
UniXML_iterator it = *this;
if (!curNode->prev)
{
curNode=curNode->prev;
return it;
}
for(;;)
{
curNode=curNode->prev;
if (getName() == "text" || getName() == "comment")
continue;
else
break;
}
return it;
}
// -------------------------------------------------------------------------------
......@@ -4,7 +4,7 @@
SUBDIRS=JrnTests
noinst_PROGRAMS = passivetimer unixml ui umutex conftest
noinst_PROGRAMS = passivetimer unixml ui umutex conftest iterator_test
passivetimer_SOURCES = passivetimer.cc
passivetimer_LDADD = $(top_builddir)/lib/libUniSet.la
......@@ -14,6 +14,10 @@ unixml_SOURCES = unixml.cc
unixml_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS}
unixml_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS}
iterator_test_SOURCES = iterator_test.cc
iterator_test_LDADD = $(top_builddir)/lib/libUniSet.la
iterator_test_CPPFLAGS = -I$(top_builddir)/include
ui_SOURCES = ui.cc
ui_LDADD = $(top_builddir)/lib/libUniSet.la
ui_CPPFLAGS = -I$(top_builddir)/include
......
#include <iostream>
#include <algorithm>
using namespace std;
#include "Exceptions.h"
#include "UniXML.h"
#include "UniSetTypes.h"
void check( const std::string name, const std::string true_res, const std::string your_res )
{
cout<<name<<endl;
cout<<"Correct result: "<<true_res<<endl;
if( your_res == true_res )
cout<<"Your result: "<<your_res<<"\n"<<endl;
else
cout<<"Your result - ERROR!"<<"\n"<<endl;
}
void myf(xmlNode it)
{
cout<<it.name<<endl;
}
int main()
{
UniXML xml("iterator_test.xml");
UniXML::iterator it=xml.begin();
it.find("messages");
check( "Check find():", "messages", it.getName() );
it=xml.begin();
it.find("d7");
check( "Check find():", "d7", it.getName() );
it=xml.begin();
it.findName("c5","6abc");
check( "Check findName():", "c5", it.getName() );
it=xml.begin();
it.findName("messages","messages");
check( "Check findName():", "messages", it.getName() );
it=xml.begin();
it.find("UniSet");
it++;
++it;
check( "Check iterator ++ :", "ObjectsMap", it.getName() );
it=xml.begin();
it.find("testII");
it++;
it--;
--it;
check( "Check iterator -- :", "a2", it.getName() );
it=xml.begin();
it.goChildren();
cout<<"Check algorythm 'for_each()':\n";
for_each(it,xml.end(),myf);
cout<<"\nCorrect result for algoryhtm 'for_each()':\n"<<"UniSet \n"<<"dlog \n"
<<"ObjectsMap \n"<<"messages \n";
return 0;
}
<?xml version = '1.0' encoding = 'UTF-8' ?>
<UNISETPLC>
<UniSet>
<test name="testattr_0">
<a1 name="1abc"/>
<a2 name="2abc"/>
<testI name="testattr_1">
<b3 name="3abc"/>
<a2 name="3abc"/>
<testII name="testattr_2">
<c4 name="4abc"/>
<c5 name="5abc"/>
</testII>
<testIII name="testattr_3">
<d6 name="6abc"/>
<d7 name="7abc"/>
<a2 name="4abc"/>
<c5 name="6abc"/>
</testIII>
</testI>
<testIV name="testattr_4">
<e8 name="8abc"/>
<e9>
<f10 name="10abc">
</f10>
</e9>
</testIV>
<a2 name="5abc"/>
<c5 name="7abc"/>
</test>
</UniSet>
<dlog name="dlog" levels="" file=""/>
<ObjectsMap idfromfile="1">
</ObjectsMap>
<messages name="messages" idfromfile="1" >
</messages>
</UNISETPLC>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment