|
From: 王远天 <xia...@ho...> - 2014-04-02 01:43:06
|
From: xia...@ho...
To: jso...@li...
Subject: Powerful Json::Path
Date: Tue, 1 Apr 2014 09:54:45 +0000
Json::Value v;v["a"]["b"][0u] = 1;
Json::Path p("a.b.c");const Json::Value &ref = p.resolve(v);// assert
The above code with course an assert when call "resolve".That is because "resolve" do not process except conditions.
const Value &Path::resolve( const Value &root ) const{ const Value *node = &root; for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) { const PathArgument &arg = *it; if ( arg.kind_ == PathArgument::kindIndex ) { if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) { // Error: unable to resolve path (array value expected at position... } node = &((*node)[arg.index_]); } else if ( arg.kind_ == PathArgument::kindKey ) { if ( !node->isObject() ) { // Error: unable to resolve path (object value expected at position...) } node = &((*node)[arg.key_]); if ( node == &Value::null ) { // Error: unable to resolve path (object has no member named '' at position...) } } } return *node;}
Users call "resolve" means they must take the risk of fatal error.so "Path" is useless. But Json::Path should be more powerfull.Suppose we have a function named "bad" in class Value, which specified the value itself is bad. User shall check it like below:
Json::Value v;v["a"]["b"][0u] = 1;
Json::Path p("a.b.c");const Json::Value &ref = p.resolve(v);// will not assert
if (ref.bad()){ std::cout << "ref is bad." << std::endl; ref = 2; // any operation to bad value will cause assert}
all we need to do is two step:1,declare a static member in Json::Value: static Value bad; bool bad() const { return &bad == this; }2,replace each "// Error: *" line to return Value::bad;
further morewe could use Json::Path to resolve the exact type value, Like this:
Json::Value v;v["a"]["b"][0u] = 1;
Json::Path p("a.b[0]");Json::Integer i = p.resolveInt(v);
if (i.bad()){ //do something}
Wish this features will be added to new version. |