36 m_msg(
"Error in XML file") {
38 m_msg +=
" at line " +
int2str(line+1);
77 m_msg +=
"<" + opentag +
"> paired with </" + closetag +
">.\n";
81 return "XML_TagMismatch";
102 std::string child,
int line=0) :
104 m_msg +=
" The XML Node \"" + parent +
105 "\", does not contain a required\n" +
106 " XML child node named \""
108 ostringstream ss(ostringstream::out);
110 m_msg += ss.str() +
"\n";
114 return "XML_NoChild";
120 XML_Reader::XML_Reader(std::istream& input) :
142 std::string::size_type istart = 0)
144 string::size_type iloc, icurrent, len;
148 iloc = s.find(q, icurrent);
152 char cm1 = s[iloc-1];
154 if (iloc >= (len -1)) {
166 const char q1 =
'\'';
170 string::size_type iloc1, iloc2, ilocStart = 0;
178 if (iloc1 < ilocStart) {
196 rstring = s.substr(ilocStart + 1, iloc1 - 1);
200 return static_cast<int>(iloc1)+1;
204 std::map<std::string, std::string>& attribs)
const
206 string::size_type iloc;
211 name = s.substr(0, iloc);
212 s =
stripws(s.substr(iloc+1,s.size()));
213 if (s[s.size()-1] ==
'/') {
223 attr =
stripws(s.substr(0,iloc));
227 s =
stripws(s.substr(iloc+1,s.size()));
231 if (iloc < s.size()) {
232 s =
stripws(s.substr(iloc,s.size()));
245 string name, tag =
"";
246 bool incomment =
false;
249 if (
m_s.eof() || (
getchr(ch), ch ==
'<')) {
253 char ch1 =
' ', ch2 =
' ';
263 if (ch1 ==
'-' && ch2 ==
'!') {
267 }
else if (ch ==
'>') {
269 if (ch1 ==
'-' && ch2 ==
'-') {
303 }
else if (ch !=
' ') {
310 if (front && lastch ==
' ' && ch ==
' ') {
340 m_iscomment(right.m_iscomment),
341 m_linenum(right.m_linenum)
349 XML_Node& XML_Node::operator=(
const XML_Node& right)
351 if (&right !=
this) {
352 for (
size_t i = 0; i <
m_children.size(); i++) {
366 XML_Node::~XML_Node()
369 writelog(
"XML_Node::~XML_Node: deleted a locked XML_Node: "+
name());
371 for (
size_t i = 0; i <
m_children.size(); i++) {
383 for (
size_t i = 0; i <
m_children.size(); i++) {
403 addChild(
"comment", comment);
420 XML_Node& XML_Node::addChild(
const std::string& sname)
425 XML_Node& XML_Node::addChild(
const std::string& name,
const std::string& value)
432 XML_Node& XML_Node::addChild(
const std::string& name,
const doublereal value,
433 const std::string&
fmt)
442 vector<XML_Node*>::iterator i;
453 return std::string(
"");
459 if (
m_name ==
"comment") {
477 "To be removed after Cantera 2.2. Use XML_Node::value().");
488 return std::atoi(
m_value.c_str());
507 const doublereal vvalue,
const std::string&
fmt)
529 return getValue<string,string>(
m_attribs, attr,
"");
585 if (discardComments) {
587 for (
size_t i = 0; i <
m_children.size(); i++) {
610 string msg=
"XML_Node "+
name()+
" is required to have an attribute named " + a +
611 " with the value \"" + v +
"\", but instead the value is \"" +
attrib(a);
616 const std::string& idTarget)
const
620 std::string idattrib =
id();
621 if (
name() == nameTarget) {
622 if (idTarget ==
"" || idTarget == idattrib) {
626 for (
size_t n = 0; n <
m_children.size(); n++) {
628 if (sc->
name() == nameTarget) {
629 if (idTarget ==
"") {
633 if (idTarget == idattrib) {
638 for (
size_t n = 0; n <
m_children.size(); n++) {
640 scResult = sc->
findNameID(nameTarget, idTarget);
649 const std::string& idTarget,
const int index_i)
const
653 std::string idattrib =
id();
654 std::string ii =
attrib(
"index");
655 std::string index_s =
int2str(index_i);
657 if (
name() == nameTarget) {
658 if (idTarget ==
"" || idTarget == idattrib) {
664 for (
size_t n = 0; n <
m_children.size(); n++) {
666 if (sc->
name() == nameTarget) {
668 int indexR = atoi(ii.c_str());
670 if (idTarget == idattrib || idTarget ==
"") {
688 if (
attrib(
"id") == id_) {
694 for (
size_t i = 0; i <
nChildren(); i++) {
705 const std::string& val,
int depth)
const
708 if (
attrib(attr) == val) {
715 for (
size_t i = 0; i < n; i++) {
716 r =
m_children[i]->findByAttr(attr, val, depth - 1);
732 for (
size_t i = 0; i <
nChildren(); i++) {
749 for (
size_t i = 0; i <
nChildren(); i++) {
761 s <<
"<?xml version=\"1.0\"?>" << endl;
769 map<string, string> node_attribs;
772 node_attribs.clear();
782 if (nm[nm.size() - 1] ==
'/') {
783 nm2 = nm.substr(0,nm.size()-1);
788 node = &node->addChild(nm2);
791 node->
attribs() = node_attribs;
794 }
else if (nm[0] !=
'/') {
795 if (nm[0] !=
'!' && nm[0] !=
'-' && nm[0] !=
'?') {
800 node = &node->addChild(nm);
804 node->
attribs() = node_attribs;
806 }
else if (nm.substr(0,2) ==
"--") {
807 if (nm.substr(nm.size()-2,2) ==
"--") {
812 if (node->
name() != nm.substr(1,nm.size()-1)) {
827 map<string,string>::const_iterator b =
m_attribs.begin();
833 const vector<XML_Node*> &vsc = node_dest->
children();
834 for (
size_t n = 0; n <
m_children.size(); n++) {
839 for (
size_t idc = 0; idc < ndc; idc++) {
867 (void) node_dest->addChild(sc->
name());
883 map<string,string>::const_iterator b =
m_attribs.begin();
887 const vector<XML_Node*> &vsc = node_dest->
children();
889 for (
size_t n = 0; n <
m_children.size(); n++) {
893 (void) node_dest->addChild(sc->
name());
902 for (
size_t i = 0; i <
m_children.size(); i++) {
910 for (
size_t i = 0; i <
m_children.size(); i++) {
916 std::vector<XML_Node*>& children_)
const
918 warn_deprecated(
"XML_Node::getChildren",
"To be removed after Cantera 2.2."
919 "Use overload that returns the vector of XML_Node pointers.");
920 for (
size_t i = 0; i <
nChildren(); i++) {
922 children_.push_back(&
child(i));
929 std::vector<XML_Node*> children_;
930 for (
size_t i = 0; i <
nChildren(); i++) {
932 children_.push_back(&
child(i));
940 string::size_type iloc;
943 std::multimap<std::string,XML_Node*>::const_iterator i;
946 iloc = loc.find(
'/');
948 cname = loc.substr(0,iloc);
949 loc = loc.substr(iloc+1, loc.size());
952 return i->second->child(loc);
973 string indent(level,
' ');
980 s << endl << indent <<
"<!--";
985 if (! isspace(m_value[m_value.size()-1])) {
992 s << indent <<
"<" <<
m_name;
993 map<string,string>::const_iterator b =
m_attribs.begin();
995 s <<
" " << b->first <<
"=\"" << b->second <<
"\"";
1004 string::size_type ieol = vv.find(
'\n');
1007 ieol = vv.find(
'\n');
1010 s << endl << indent <<
" ";
1012 size_t jf = ieol - 1;
1013 for (
int j = 0; j < (int) ieol; j++) {
1014 if (! isspace(vv[j])) {
1019 s << endl << indent <<
" " << vv.substr(jf,ieol-jf);
1021 vv = vv.substr(ieol+1);
1023 size_t lll = vv.size() - 1;
1026 for (
size_t j = 0; j < lll; j++) {
1027 if (! isspace(vv[j])) {
1033 s << endl << indent <<
" " << vv.substr(jf);
1039 s << endl << indent;
1041 bool doSpace =
true;
1042 bool doNewLine =
false;
1043 size_t ll =
m_value.size() - 1;
1047 if (m_name ==
"floatArray") {
1055 s << endl << indent <<
" ";
1060 if (doSpace && (! isspace(
m_value[0]))) {
1068 if (doSpace && (! isspace(m_value[ll]))) {
1072 s << endl << indent;
1076 if (numRecursivesAllowed > 0) {
1077 for (
size_t i = 0; i <
m_children.size(); i++) {
1079 m_children[i]->write_int(s,level + 2, numRecursivesAllowed - 1);
1083 s << endl << indent;
1085 s <<
"</" << m_name <<
">";
1091 write_int(s, level, numRecursivesAllowed);
1103 for (
size_t i = 0; i <
m_children.size(); i++) {
1109 const std::string& idtarget)
1117 string rname = root->
name();
1118 if (rname ==
"phase") {
1119 if (idtarget ==
"") {
1122 idattrib = root->
id();
1123 if (idtarget == idattrib) {
1128 const vector<XML_Node*> &vsc = root->
children();
1129 for (
size_t n = 0; n < root->
nChildren(); n++) {
1131 if (sc->
name() ==
"phase") {
1132 if (idtarget ==
"") {
1135 idattrib = sc->
id();
1136 if (idtarget == idattrib) {
1141 for (
size_t n = 0; n < root->
nChildren(); n++) {
void setName(const std::string &name_)
Sets the name of the XML node.
Class representing a specific type of XML file formatting error.
static string::size_type findUnbackslashed(const std::string &s, const char q, std::string::size_type istart=0)
Find the first position of a character, q, in string, s, which is not immediately preceded by the bac...
XML_Node * findByAttr(const std::string &attr, const std::string &val, int depth=100000) const
This routine carries out a recursive search for an XML node based on an attribute of each XML node...
integer int_value() const
Return the value of an XML node as a single int.
void _require(const std::string &a, const std::string &v) const
Require that the current XML node have an attribute named by the first argument, a, and that this attribute have the the string value listed in the second argument, v.
std::vector< XML_Node * > m_children
Vector of pointers to child nodes.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
XML_Node * findNameID(const std::string &nameTarget, const std::string &idTarget) const
This routine carries out a recursive search for an XML node based on both the XML element name and th...
int findQuotedString(const std::string &aline, std::string &rstring) const
Searches a string for the first occurrence of a valid quoted string.
std::string readTag(std::map< std::string, std::string > &attribs)
Reads an XML tag into a string.
XML_Node * findXMLPhase(XML_Node *root, const std::string &idtarget)
Search an XML_Node tree for a named phase XML_Node.
virtual ~XML_Error()
destructor
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
void clear()
Clear the current node and everything under it.
const std::vector< XML_Node * > & children() const
Return an unchangeable reference to the vector of children of the current node.
Various templated functions that carry out common vector operations (see Templated Utility Functions)...
const size_t npos
index returned by functions to indicate "no position"
XML_TagMismatch(const std::string &opentag, const std::string &closetag, int line=0)
Constructor.
static std::string fmt(const std::string &r, size_t n)
XML_Error(int line=0)
Constructor.
void unlock()
Unset the lock for this node and all of its children.
std::map< std::string, std::string > & attribs()
Returns a changeable value of the attributes map for the current node.
Class XML_Node is a tree-based representation of the contents of an XML file.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
XML_Node * findNameIDIndex(const std::string &nameTarget, const std::string &idTarget, const int index) const
This routine carries out a search for an XML node based on both the XML element name and the attribut...
virtual std::string getClass() const
Method overridden by derived classes to indicate their type.
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, (see Input File Handling, Diagnostic Output, and Writing messages to the screen).
std::map< std::string, std::string > m_attribs
Storage of attributes for a node.
const std::map< std::string, std::string > & attribsConst() const
Returns an unchangeable value of the attributes map for the current node.
XML_Node * setParent(XML_Node *const p)
Sets the pointer for the parent node of the current node.
std::string m_value
Value of the XML node.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
void addValue(const std::string &val)
Modify the value for the current node.
Class XML_Reader reads an XML file into an XML_Node object.
XML_NoChild(const XML_Node *p, const std::string &parent, std::string child, int line=0)
Constructor.
const XML_Node * findByName(const std::string &nm, int depth=100000) const
This routine carries out a recursive search for an XML node based on the name of the node...
void addComment(const std::string &comment)
Add a child node to the current node containing a comment.
void parseTag(const std::string &tag, std::string &name, std::map< std::string, std::string > &attribs) const
parseTag parses XML tags, i.e., the XML elements that are in between angle brackets.
std::string stripws(const std::string &s)
Strip the leading and trailing white space from a string.
bool m_locked
Lock for this node.
virtual std::string getClass() const
Method overridden by derived classes to indicate their type.
XML_Node * m_root
Pointer to the root XML_Node for the current node.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
void lock()
Set the lock for this node and all of its children.
bool m_iscomment
True if the current node is a comment node.
std::string name() const
Returns the name of the XML node.
XML_Node(const std::string &nm="--", XML_Node *const parent=0)
Constructor for XML_Node, representing a tree structure.
Classes providing support for XML data files.
Base class for exceptions thrown by Cantera classes.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
std::string m_msg
String message for the error.
void write(std::ostream &s, const int level=0, int numRecursivesAllowed=60000) const
Write an XML subtree to an output stream.
XML_Node & mergeAsChild(XML_Node &node)
Merge an existing node as a child node to the current node.
XML_Node * m_parent
Pointer to the parent XML_Node for the current node.
void addAttribute(const std::string &attrib, const std::string &value)
Add or modify an attribute of the current node.
void setLineNumber(const int n)
Set the line number.
virtual std::string getMessage() const
Method overridden by derived classes to format the error message.
void copy(XML_Node *const node_dest) const
Copy all of the information in the current XML_Node tree into the destination XML_Node tree...
void setRoot(const XML_Node &root)
Set the root XML_Node value within the current node.
std::string value() const
Return the value of an XML node as a string.
std::string m_name
XML node name of the node.
int lineNumber() const
Return the line number.
std::string readValue()
Return the value portion of an XML element.
std::string id() const
Return the id attribute, if present.
void removeChild(const XML_Node *const node)
Remove a child from this node's list of children.
int m_line
Line number of the file.
XML_Node * findID(const std::string &id, const int depth=100) const
This routine carries out a recursive search for an XML node based on the XML element attribute...
Contains declarations for string manipulation functions within Cantera.
void writeHeader(std::ostream &s)
Write the header to the XML file to the specified ostream.
bool isComment() const
Boolean function indicating whether a comment.
std::string operator[](const std::string &attr) const
The operator[] is overloaded to provide a lookup capability on attributes for the current XML element...
void writelog(const std::string &msg)
Write a message to the screen.
doublereal fp_value() const
Return the value of an XML node as a single double.
XML_Node & root() const
Return the root of the current XML_Node tree.
Classs representing a generic XML error condition.
XML_Node * parent() const
Returns a pointer to the parent node of the current node.
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
int m_linenum
The member data m_linenum.
void build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
std::multimap< std::string, XML_Node * > m_childindex
Map containing an index between the node name and the pointer to the node.
void copyUnion(XML_Node *const node_dest) const
Copy all of the information in the current XML_Node tree into the destination XML_Node tree...
size_t nChildren(bool discardComments=false) const
Return the number of children.
void getChildren(const std::string &name, std::vector< XML_Node * > &children) const
Get a vector of pointers to XML_Node containing all of the children of the current node which matches...
std::istream & m_s
Input stream containing the XML file.
Class representing a specific type of XML file formatting error.
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
void write_int(std::ostream &s, int level=0, int numRecursivesAllowed=60000) const
Write an XML subtree to an output stream.
void getchr(char &ch)
Read a single character from the input stream and returns it.
std::string operator()() const
Overloaded parenthesis operator returns the value of the Node.