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

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

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