diff --git a/Cantera/src/xml.cpp b/Cantera/src/xml.cpp index 0f11a9f93..75c1225ab 100755 --- a/Cantera/src/xml.cpp +++ b/Cantera/src/xml.cpp @@ -276,7 +276,7 @@ namespace Cantera { XML_Node::XML_Node(string nm, XML_Node* p, int n) - : m_name(nm), m_level(0), m_parent(p), m_nchildren(0), + : m_name(nm), m_parent(p), m_nchildren(0), m_n(n), m_iscomment(false) { if (!p) m_root = this; else m_root = &p->root(); @@ -309,7 +309,8 @@ namespace Cantera { XML_Node& XML_Node::addChild(string name) { int n = m_children.size(); - m_children.push_back(new XML_Node(name, this, n)); + XML_Node *xxx = new XML_Node(name, this, n); + m_children.push_back(xxx); m_nchildren = m_children.size(); m_childindex[name] = m_children.back(); m_children.back()->setParent(this); @@ -324,10 +325,51 @@ namespace Cantera { m_childindex.erase(node->name()); } - XML_Node* XML_Node::findID(const string& id, int depth) { + /** + * This routine carries out a search for an XML node based + * on both the xml element name and the attribute ID. + * If exact matches are found for both fields, the pointer + * to the matching XML Node is returned. + * + * The ID attribute may be defaulted by setting it to "". + * In this case the pointer to the first xml element matching the name + * is returned. + * + * This algorithm does a lateral search of first generation children + * first before diving deeper into each tree branch. + */ + XML_Node* XML_Node:: + findNameID(const string &nameTarget, const string &idTarget) const { + XML_Node *scResult = 0; + XML_Node *sc; + string idattrib = id(); + int n; + if (name() == nameTarget) { + if (idTarget == "" || idTarget == idattrib) { + return const_cast(this); + } + } + for (n = 0; n < m_nchildren; n++) { + sc = m_children[n]; + if (sc->name() == nameTarget) { + if (idTarget == "") return sc; + idattrib = sc->id(); + if (idTarget == idattrib) return sc; + } + } + for (n = 0; n < m_nchildren; n++) { + sc = m_children[n]; + scResult = sc->findNameID(nameTarget, idTarget); + if (scResult) return scResult; + } + return scResult; + } + + + XML_Node* XML_Node::findID(const string& id, int depth) const { if (hasAttrib("id")) { if (attrib("id") == id) { - return this; + return const_cast(this); } } if (depth > 0) { @@ -593,11 +635,10 @@ namespace Cantera { * main recursive routine. It doesn't put a final endl * on. This is fixed up in the public method. */ - void XML_Node::write_int(ostream& s, int level) { + void XML_Node::write_int(ostream& s, int level) const { if (m_name == "") return; - m_level = level; string indent(level, ' '); if (m_iscomment) { /* @@ -765,7 +806,8 @@ namespace Cantera { #endif - XML_Node * const findXMLPhase(XML_Node *root, string idtarget) { + XML_Node * findXMLPhase(XML_Node *root, + const string &idtarget) { XML_Node *scResult = 0; XML_Node *sc; if (!root) return 0; diff --git a/Cantera/src/xml.h b/Cantera/src/xml.h index b28362a07..a0ad069b7 100755 --- a/Cantera/src/xml.h +++ b/Cantera/src/xml.h @@ -114,11 +114,6 @@ namespace Cantera { } bool hasAttrib(string a) const { return (m_attribs.find(a) != m_attribs.end()); - //if (m_attribs[a] != "") return true; - //else { - // m_attribs.erase(a); - // return false; - //} } @@ -130,33 +125,46 @@ namespace Cantera { int number() const { return m_n; } XML_Node& child(int n) const { return *m_children[n]; } - //const XML_Node& child(int n) const { return *m_children[n]; } vector& children() { return m_children; } const vector& children() const { return m_children; } int nChildren() const { return m_nchildren; } void build(istream& f); - XML_Node* findID(const string& id, int depth=100); + /** + * This routine carries out a search for an XML node based + * on both the xml element name and the attribute ID. + * If exact matches are found for both fields, the pointer + * to the matching XML Node is returned. + * + * The ID attribute may be defaulted by setting it to "". + * In this case the pointer to the first xml element matching the name + * only is returned. + * @internal + * This algorithm does a lateral search of first generation children + * first before diving deeper into each tree branch. + */ + XML_Node* findNameID(const string &nameTarget, + const string &idTarget) const; + + XML_Node* findID(const string& id, int depth=100) const; XML_Node* findByAttr(const string& attr, const string& val); XML_Node* findByName(const string& nm); void getChildren(string name, vector& children) const; XML_Node& child(string loc) const; void write(ostream& s, int level = 0); - //const XML_Node* getRef() const; XML_Node& root() const { return *m_root; } void setRoot(XML_Node& root) { m_root = &root; } void copyUnion(XML_Node *node_dest); void copy(XML_Node *node_dest); private: - void write_int(ostream& s, int level = 0); + void write_int(ostream& s, int level = 0) const; protected: string m_name; string m_value; - int m_level; map m_childindex; map m_attribs; XML_Node* m_parent; @@ -259,11 +267,9 @@ namespace Cantera { } }; - - //XML_Node* find_XML(string src, XML_Node* root=0, - // string id="", string loc="", string name=""); + + XML_Node * findXMLPhase(XML_Node* root, const string &id); - XML_Node * const findXMLPhase(XML_Node* root, string id); } #endif