const AXmlElement *AXmlElement::findElement(const AString& xpath) const { LIST_AString xparts; xpath.split(xparts, '/'); if (xparts.size() > 0) { if ('/' == xpath.at(0)) { if (isNameEquals(xparts.front())) { xparts.pop_front(); if (xparts.size() > 0) return _get(xparts); else return this; } else return NULL; } else { if (xparts.size() > 0) return _get(xparts); else return NULL; } } else { return this; } }
void testSplit(int& iRet) { LIST_AString names; AString str0("path0/path1/path2"); str0.split(names, '/'); ASSERT_UNIT_TEST(names.size() == 3, "AString::split", "0", iRet); LIST_AString::iterator it = names.begin(); ASSERT_UNIT_TEST(!(*it).compare("path0"), "AString::split", "1", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path1"), "AString::split", "2", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path2"), "AString::split", "3", iRet); ++it; ASSERT_UNIT_TEST(it == names.end(), "AString::split", "3a", iRet); str0.assign("\\\\\\\\path0\\\\\\path1\\\\path2\\"); names.clear(); str0.split(names, '\\'); ASSERT_UNIT_TEST(names.size() == 3, "AString::split", "4", iRet); it = names.begin(); ASSERT_UNIT_TEST(!(*it).compare("path0"), "AString::split", "5", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path1"), "AString::split", "6", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path2"), "AString::split", "7", iRet); ++it; ASSERT_UNIT_TEST(it == names.end(), "AString::split", "8", iRet); str0.assign("_path0_path1_path2"); names.clear(); str0.split(names, '_'); ASSERT_UNIT_TEST(names.size() == 3, "AString::split", "9", iRet); it = names.begin(); ASSERT_UNIT_TEST(!(*it).compare("path0"), "AString::split", "10", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path1"), "AString::split", "11", iRet); ++it; ASSERT_UNIT_TEST(!(*it).compare("path2"), "AString::split", "12", iRet); ++it; ASSERT_UNIT_TEST(it == names.end(), "AString::split", "13", iRet); }
AXmlElement& AXmlElement::addContent( AXmlElement *pnode, const AString& path, // = AConstant::ASTRING_EMPTY bool insertIntoFront // = false ) { if (path.isEmpty() || path.equals(AConstant::ASTRING_SLASH)) { AASSERT(this, m_Content.size() < DEBUG_MAXSIZE_AXmlElement); //Debug only limit AASSERT(this, pnode); pnode->setParent(this); if (insertIntoFront) m_Content.push_front(pnode); else m_Content.push_back(pnode); } else { LIST_AString parts; path.split(parts, '/'); if (!parts.size()) ATHROW(this, AException::InvalidParameter); AXmlElement *pNewParent = _createAndAppend(parts, this, insertIntoFront); AASSERT_EX(this, pNewParent, path); pNewParent->addContent(pnode, AConstant::ASTRING_EMPTY, insertIntoFront); } return *this; }
size_t AXmlElement::_find(const AString& path, AXmlElement::CONTAINER& result) { AString strAttribute; AString strPath(path); bool leadingSlash = false; if ('/' == strPath.at(0)) { leadingSlash = true; //a_Signals that slash leads the path so much include current name } //a_Remove the leading name (which should be this element's name) LIST_AString listPath; strPath.split(listPath, '/'); if (leadingSlash) { if (0 == listPath.size()) { //a_ "/" selects current node result.push_back(this); return 1; } else if (0 != listPath.front().compare(m_Name)) { //a_First token MUST be the name of this element if / leads AString str("Absolute path must start with the name of the current root element: root=/"); str.append(m_Name); str.append(" while path="); str.append(path); ATHROW_EX(this, AException::ProgrammingError, str); } } else if (0 == listPath.size()) { //a_ "/" selects current node result.push_back(this); return 1; } else { //a_Relative path implies this node is first listPath.push_front(m_Name); } return _nonconst_find(listPath, result); }
size_t AXmlElement::_const_find(LIST_AString listPath, AXmlElement::CONST_CONTAINER& result) const { if (isNameEquals(listPath.front())) { listPath.pop_front(); size_t ret = 0; switch(listPath.size()) { case 0: //a_This node is it result.push_back(this); ++ret; break; case 1: { //a_Include immediate children nodes CONTAINER::const_iterator cit = m_Content.begin(); while (cit != m_Content.end()) { // Name only, add if martches if ((*cit)->isNameEquals(listPath.front())) { result.push_back(*cit); ++ret; } ++cit; } } break; default: { //a_Recurse deeper for each element CONTAINER::const_iterator cit = m_Content.begin(); while (cit != m_Content.end()) { if ((*cit)->isNameEquals(listPath.front())) { ret += (*cit)->_const_find(listPath, result); } ++cit; } } break; } return ret; } else return 0; }
AXmlElement *AXmlElement::_addElement(const AString& path, bool overwrite, bool insertIntoFront) { if (m_Name.isEmpty()) ATHROW_EX(this, AException::InvalidObject, ASWNL("AXmlElement does not have a name")); LIST_AString xparts; path.split(xparts, '/'); if (!xparts.size()) ATHROW(this, AException::InvalidParameter); //a_Check is absolute is used and if root name matches this element if ('/' == path.at(0) && xparts.size() > 0) { //a_xpath starts with /, make sure names match if (isNameEquals(xparts.front())) xparts.pop_front(); else { AString str("Path specified ("); str.append(path); str.append(") is absolute and does not match this element's name: "); str.append(m_Name); ATHROW_EX(this, AException::InvalidPath, str); } } //a_Skipped over root or relative path specified AXmlElement *p = NULL; if (xparts.size() > 0) { if (overwrite) p = _getOrCreate(xparts, this, insertIntoFront); else p = _createAndAppend(xparts, this, insertIntoFront); } else p = this; return p; }