improved Find() in SetSet

pull/40/head
Matchman Green 2012-05-12 11:47:51 +08:00
parent ceffebb097
commit c1c1916eb7
7 changed files with 75 additions and 18 deletions

View File

@ -95,9 +95,15 @@ void Entry::Update( const Json& entry )
void Entry::Update( const xml::Node& n )
{
m_title = n["title"] ;
m_etag = n["@gd:etag"] ;
m_filename = n.ChildValue( "docs:suggestedFilename" ) ;
m_title = n["title"] ;
m_etag = n["@gd:etag"] ;
m_filename = n["docs:suggestedFilename"] ;
m_content_src = n["content"]["@src"] ;
m_self_href = n["link"].Find( "@rel", "self" )["@href"] ;
xml::NodeSet parents = n["link"].Find( "@rel", "http://schemas.google.com/docs/2007#parent" ) ;
m_parent_hrefs.resize( parents.size() ) ;
std::copy( parents.begin(), parents.end(), m_parent_hrefs.begin() ) ;
}
std::string Entry::Parent( const Json& entry )

View File

@ -81,6 +81,8 @@ private :
std::string m_etag ;
std::string m_resource_id ;
std::vector<std::string> m_parent_hrefs ;
std::string m_self_href ;
std::string m_content_src ;
std::string m_parent_href ;

View File

@ -293,6 +293,12 @@ void Node::AddNode( const Node& node )
m_ptr->Add( node.m_ptr->AddRef() ) ;
}
void Node::AddNode( iterator first, iterator last )
{
for ( iterator i = first ; i != last ; ++i )
AddNode( *i ) ;
}
NodeSet Node::operator[]( const std::string& name ) const
{
assert( m_ptr != 0 ) ;
@ -327,6 +333,11 @@ std::string Node::Value() const
return m_ptr->Value() ;
}
Node::operator std::string() const
{
return Value() ;
}
std::ostream& operator<<( std::ostream& os, const Node& node )
{
if ( node.GetType() == Node::element )
@ -415,10 +426,4 @@ std::string Node::Attr( const std::string& attr ) const
return imp != 0 ? imp->Value() : "" ;
}
std::string Node::ChildValue( const std::string& name ) const
{
NodeSet r = operator[]( name ) ;
return r.empty() ? "" : r.begin()->Value() ;
}
} } // end namespace

View File

@ -52,9 +52,11 @@ public :
Node AddElement( const std::string& name ) ;
Node AddText( const std::string& text ) ;
void AddNode( const Node& node ) ;
void AddNode( iterator first, iterator last ) ;
void AddAttribute( const std::string& name, const std::string& val ) ;
NodeSet operator[]( const std::string& name ) const ;
operator std::string() const ;
const std::string& Name() const ;
std::string Value() const ;
@ -76,8 +78,6 @@ public :
NodeSet Attr() const ;
std::string Attr( const std::string& attr ) const ;
std::string ChildValue( const std::string& name ) const ;
private :
explicit Node( Impl *impl ) ;

View File

@ -22,8 +22,16 @@
#include <algorithm>
#include <stdexcept>
#include <iostream>
namespace gr { namespace xml {
NodeSet::NodeSet() :
m_first( m_tmp.begin() ),
m_last( m_tmp.end() )
{
}
NodeSet::NodeSet( iterator first, iterator last ) :
m_first( first ),
m_last( last )
@ -39,15 +47,45 @@ NodeSet::iterator NodeSet::end() const
{
return m_last ;
}
Node NodeSet::Find( const std::string& attr, const std::string& value ) const
/*! This function search the members in the node set. If any members in the node
set has a children named \a name , with value equal to \a value , it will
be returned.
\param name name to be found. prefix with '@' for attributes
\param value value to be matched.
\return the node set contained all children nodes that matches \a name and \a value
*/
NodeSet NodeSet::Find( const std::string& name, const std::string& value ) const
{
NodeSet result ;
for ( iterator i = m_first ; i != m_last ; ++i )
{
if ( i->Attr( attr ) == value )
return *i ;
NodeSet cand = (*i)[name] ;
for ( iterator j = cand.m_first ; j != cand.m_last ; ++j )
{
if ( j->Value() == value )
{
result.Add( *i ) ;
break ;
}
}
}
throw std::runtime_error( "can't find element with " + attr + " is " + value ) ;
return result ;
}
void NodeSet::Add( const Node& n )
{
// the tmp node is not used, that means the first,last iterators points to elsewhere
if ( m_tmp.size() == 0 )
{
m_tmp.AddNode( m_first, m_last ) ;
}
m_tmp.AddNode( n ) ;
// the iterators may be invalidated after adding the node
m_first = m_tmp.begin() ;
m_last = m_tmp.end() ;
}
NodeSet NodeSet::operator[]( const std::string& name ) const
@ -71,7 +109,7 @@ Node NodeSet::front() const
NodeSet::operator std::string() const
{
return front().Value() ;
return empty() ? "" : front().Value() ;
}
bool NodeSet::empty() const

View File

@ -33,7 +33,10 @@ public :
typedef Node::iterator iterator ;
public :
NodeSet() ;
NodeSet( iterator first, iterator last ) ;
void Add( const Node& n ) ;
iterator begin() const ;
iterator end() const ;
@ -41,13 +44,14 @@ public :
std::size_t size() const ;
Node front() const ;
Node Find( const std::string& attr, const std::string& value ) const ;
NodeSet Find( const std::string& name, const std::string& value ) const ;
// forwarding common Node operations to Node
operator std::string() const ;
NodeSet operator[]( const std::string& name ) const ;
private :
Node m_tmp ;
iterator m_first ;
iterator m_last ;
} ;

View File

@ -45,6 +45,8 @@ void EntryTest::TestXml( )
Entry subject( root["entry"].front() ) ;
GRUT_ASSERT_EQUAL( "snes", subject.Title() ) ;
GRUT_ASSERT_EQUAL( "\"WxYPGE8CDyt7ImBk\"", subject.ETag() ) ;
GRUT_ASSERT_EQUAL( "https://docs.google.com/feeds/default/private/full/folder%3A0B5KhdsbryVeGMl83OEV1ZVc3cUE",
subject.SelfHref() ) ;
}
} // end of namespace grut