string xmlString::getSubTag( const tag &in, unsigned int tabNum ) { string ret; string tabs; if( (_format&Tabs) != FALSE ) { for( unsigned int x=0; x<tabNum; x++ ) { tabs += "\t"; } } if( in.type() == tag::None ) { ret += in.contents().toString(); /*if( (_format&NewLines) != FALSE ) { ret += "\n"; }*/ } else { if( in.type() == tag::Open && in.name() != "" ) { ret += tabs + getOpener( in.name(), in.attributes() ); } else if( in.type() == tag::Empty && in.name() != "" ) { ret += tabs + getOpener( in.name(), in.attributes(), TRUE ); } if( (_format&NewLines) != FALSE && ( in.size() > 1 || ( in.size() > 0 && in[0].type() != tag::None ) ) ) { ret += "\n"; } for( unsigned int x=0; x<in.size(); x++ ) { ret += getSubTag( in[x], tabNum + 1 ); } if( in.type() == tag::Open && in.name() != "" ) { if( in.size() > 1 || ( in.size() > 0 && in[0].type() != tag::None ) ) { ret += tabs; } ret += getClose( in.name() ); } if( (_format&NewLines) != FALSE ) { ret += "\n"; } } return ret; }
// gets child at the given path if type is compound or list // returns 0 on error // format: "list.42.intHolder..myInt." // (multiple dots are like one dot, dots at the end are ignored) Tag * Tag::getSubTag(std::string path) { size_t dotPos = path.find_first_of('.'); std::string first = path.substr(0, dotPos); std::string rest = ""; if (dotPos < path.length()) rest = path.substr(dotPos+1); DEBUG printf("getSubTag: path='%s', first='%s', rest='%s' at tag '%s'\n", path.c_str(), first.c_str(), rest.c_str(), name.c_str()); if (path.length() <= 0) return this; // recursion anchor if (first.length() <= 0) return getSubTag(rest); // allows "foo..bar." == "foo.bar" Tag * tag = NULL; if (isListType(type) || type == tagTypeCompound) { for (int32_t i = 0; i < getListSize(); i++) { tag = getListItemAsTag(i); if (tag == NULL) continue; // didn't get a tag ... why? if (first.compare(tag->getName()) == 0) break; else tag = NULL; // do not remember incorrect tags } } // we still found no matching tag, try interpreting first as number and getting n-th tag if (tag == NULL) { try { tag = getListItemAsTag(stoi(first)); DEBUG printf("getting tag #%i\n", stoi(first)); } catch (const std::invalid_argument& ia) { tag = NULL; } } // still no luck? we're out of ideas, return nothing if (tag == NULL) return NULL; return tag->getSubTag(rest); }
xmlString::xmlString( const tag &in, int f ) : _format( f ), _data( getSubTag( in ) ) { }