Commit 95eb3b75 authored by Pavel Vainerman's avatar Pavel Vainerman

(UniXML): рефакторинг функций поиска в UniXML::iterator.

Теперь они ищут "правильно" в ширь и в глубь от текущего узла.
parent 560123a0
......@@ -12,7 +12,7 @@
Name: libuniset2
Version: 2.0
Release: alt26
Release: alt27
Summary: UniSet - library for building distributed industrial control systems
......@@ -409,6 +409,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%changelog
* Thu Apr 16 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt27
- (UniXML): refactoring UniXML::iterator::find..
* Thu Apr 09 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt26
- (ModbusSlave): added support nbit
- (ModbusSlave): added support 0x01 (readCoilStatus) function
......
......@@ -54,8 +54,9 @@ class UniXML_iterator:
int getPIntProp( const std::string& name, int def );
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);
bool findName( const std::string& node, const std::string& searchname, bool deepfind=true );
bool find( const std::string& searchnode, bool deepfind=true);
xmlNode* findX( xmlNode* root, const std::string& searchnode, bool deepfind=true );
/*! Перейти к следующему узлу. Возвращает false, если некуда перейти */
bool goNext();
......
......@@ -379,14 +379,15 @@ bool UniXML_iterator::goChildren()
if (!curNode || !curNode->children )
return false;
xmlNode* tmp(curNode);
xmlNode* tmp = curNode;
curNode = curNode->children;
// использовать везде xmlIsBlankNode, если подходит
if ( getName() == "text" )
if( getName() == "text" )
return goNext();
if ( getName() == "comment" )
if( getName() == "comment" )
return goNext();
if ( getName().empty() )
if( getName().empty() )
{
curNode = tmp;
return false;
......@@ -441,53 +442,65 @@ void UniXML_iterator::setProp( const string& name, const string& text )
}
// -------------------------------------------------------------------------
bool UniXML_iterator::findName( const std::string& node, const std::string& searchname )
bool UniXML_iterator::findName( const std::string& nodename, const std::string& searchname, bool deepfind )
{
while( this->find(node) )
xmlNode* fnode = curNode;
while( fnode != NULL )
{
if ( searchname == getProp("name") )
fnode = this->findX(fnode,nodename,deepfind);
if ( searchname == UniXML::getProp(fnode,"name") )
{
curNode = fnode;
return true;
}
// ищем дальше
fnode = fnode->next;
}
return false;
}
// -------------------------------------------------------------------------
bool UniXML_iterator::find( const std::string& searchnode )
{
// Функция ищет "в ширину и в глубь"
// -------------------------------------------------------------------------
bool UniXML_iterator::find( const std::string& searchnode, bool deepfind )
{
xmlNode* fnode = findX(curNode,searchnode,deepfind);
if( fnode!=NULL )
{
curNode = fnode;
return true;
}
xmlNode* rnode = curNode;
while (curNode != NULL)
{
while( curNode->children )
{
curNode = curNode->children;
if ( searchnode == (const char*)curNode->name )
return true;
}
return false;
}
// -------------------------------------------------------------------------
xmlNode* UniXML_iterator::findX( xmlNode* root, const std::string& searchnode, bool deepfind )
{
if( root == NULL )
return NULL;
while( !curNode->next && curNode->parent )
{
// выше исходного узла "подыматься" нельзя
if( curNode == rnode )
break;
// Функция ищет "в ширину и в глубь" начиная с текущего узла!
xmlNode* fnode = root;
curNode = curNode->parent;
}
curNode = curNode->next;
if ( curNode && searchnode == (const char*)curNode->name )
{
return true;
while( fnode!=NULL )
{
if( searchnode == (const char*)fnode->name )
return fnode;
// идём "в глубь"
if( deepfind && fnode->children )
{
xmlNode* cnode = findX(fnode->children,searchnode);
if( cnode!=NULL )
return cnode;
}
// идём в ширину
fnode = fnode->next;
}
return false;
return NULL;
}
// -------------------------------------------------------------------------
UniXML_iterator UniXML_iterator::operator++()
......
......@@ -100,11 +100,17 @@ TEST_CASE("UniXML::iterator", "[unixml][iterator][basic]" )
it = uxml.begin();
CHECK( it.findName("TestNode","TestNode2") != 0 );
CHECK( it.find("subnode",false) );
REQUIRE( it.getProp("name") == "Test4" );
it = uxml.begin();
CHECK( it.findName("TestNode","TestNode3") != 0 );
UniXML::iterator sIt(it);
CHECK( sIt.goChildren() );
CHECK( it.find("subnode") );
REQUIRE( it.getProp("name") == "Test4" );
CHECK( sIt.find("subnode",false) );
REQUIRE( sIt.getProp("name") == "Test5" );
it = uxml.begin();
it.goChildren();
......@@ -131,3 +137,26 @@ TEST_CASE("UniXML::iterator", "[unixml][iterator][basic]" )
CHECK( it.getPIntProp("negative",20) == -10 );
CHECK( it.getPIntProp("unknown",20) == 20 );
}
// -----------------------------------------------------------------------------
TEST_CASE("UniXML::iterator::find", "[unixml][iterator-find][basic]" )
{
UniXML uxml("tests_unixml.xml");
CHECK( uxml.isOpen() );
xmlNode* cnode = uxml.findNode(uxml.getFirstNode(),"UniSet");
CHECK( cnode != NULL );
UniXML::iterator it(cnode);
it = uxml.begin();
CHECK( it.findName("TestNode","TestNode3") != 0 );
// CHECK( it.find("subnode") );
// REQUIRE( it.getProp("name") == "Test4" );
UniXML::iterator sIt(it);
sIt.goChildren();
CHECK( sIt.find("subnode") );
REQUIRE( sIt.getProp("name") == "Test5" );
}
......@@ -39,9 +39,11 @@
<TestNode name="TestNode1"/>
<TestNode name="TestNode2"/>
<TestNode name="TestNode3">
<subnode name="Test4"/>
<subnode name="Test5"/>
</TestNode>
<subnode name="Test4"/>
<TestProc name="TestProc1"
on_s="Input1_S"
lamp_c="Lamp58_C"
......
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