9 #include "cantera/base/config.h"
37 m_msg(
"Error in XML file") {
39 m_msg +=
" at line " +
int2str(line+1);
74 m_msg +=
"<" + opentag +
"> paired with </" + closetag +
">.\n";
96 std::string child,
int line=0) :
98 m_msg +=
" The XML Node \"" + parent +
99 "\", does not contain a required\n" +
100 " XML child node named \""
102 ostringstream ss(ostringstream::out);
104 m_msg += ss.str() +
"\n";
111 XML_Reader::XML_Reader(std::istream& input) :
133 std::string::size_type istart = 0)
135 string::size_type iloc, icurrent, len;
139 iloc = s.find(q, icurrent);
143 char cm1 = s[iloc-1];
145 if (iloc >= (len -1)) {
157 const char q1 =
'\'';
161 string::size_type iloc1, iloc2, ilocStart = 0;
169 if (iloc1 < ilocStart) {
187 rstring = s.substr(ilocStart + 1, iloc1 - 1);
191 return static_cast<int>(iloc1)+1;
195 std::map<std::string, std::string>& attribs)
const
197 string::size_type iloc;
202 name = s.substr(0, iloc);
203 s =
stripws(s.substr(iloc+1,s.size()));
204 if (s[s.size()-1] ==
'/') {
214 attr =
stripws(s.substr(0,iloc));
218 s =
stripws(s.substr(iloc+1,s.size()));
222 if (iloc < s.size()) {
223 s =
stripws(s.substr(iloc,s.size()));
236 string name, tag =
"";
237 bool incomment =
false;
240 if (
m_s.eof() || (
getchr(ch), ch ==
'<')) {
244 char ch1 =
' ', ch2 =
' ';
254 if (ch1 ==
'-' && ch2 ==
'!') {
258 }
else if (ch ==
'>') {
260 if (ch1 ==
'-' && ch2 ==
'-') {
294 }
else if (ch !=
' ') {
301 if (front && lastch ==
' ' && ch ==
' ') {
336 m_iscomment(right.m_iscomment),
337 m_linenum(right.m_linenum)
345 XML_Node& XML_Node::operator=(
const XML_Node& right)
347 if (&right !=
this) {
349 for (
int i = 0; i < n; i++) {
363 XML_Node::~XML_Node()
366 throw CanteraError(
"XML_Node::~XML_Node",
367 "attempt to delete locked XML_Node "+
name());
369 for (
int i = 0; i < n; i++) {
382 for (
int i = 0; i < n; i++) {
403 addChild(
"comment", comment);
427 XML_Node& XML_Node::addChild(
const std::string& sname)
432 m_childindex.insert(pair<const std::string, XML_Node*>(sname, xxx));
440 return addChild(std::string(cstring));
443 XML_Node& XML_Node::addChild(
const std::string& name_,
const std::string& value_)
450 XML_Node& XML_Node::addChild(
const std::string& name_,
const doublereal value_,
451 const std::string& fmt)
460 vector<XML_Node*>::iterator i;
472 return std::string(
"");
478 if (
m_name ==
"comment") {
505 return std::atoi(
m_value.c_str());
524 const doublereal value_,
const std::string& fmt)
536 std::map<std::string,std::string>::const_iterator i =
m_attribs.find(attr);
596 if (discardComments) {
621 string msg=
"XML_Node "+
name()+
" is required to have an attribute named " + a +
622 " with the value \"" + v +
"\", but instead the value is \"" +
attrib(a);
628 const std::string& idTarget)
const
632 std::string idattrib =
id();
633 if (
name() == nameTarget) {
634 if (idTarget ==
"" || idTarget == idattrib) {
640 if (sc->
name() == nameTarget) {
641 if (idTarget ==
"") {
645 if (idTarget == idattrib) {
652 scResult = sc->
findNameID(nameTarget, idTarget);
661 const std::string& idTarget,
const int index_i)
const
665 std::string idattrib =
id();
666 std::string ii =
attrib(
"index");
667 std::string index_s =
int2str(index_i);
669 if (
name() == nameTarget) {
670 if (idTarget ==
"" || idTarget == idattrib) {
678 if (sc->
name() == nameTarget) {
680 int indexR = atoi(ii.c_str());
682 if (idTarget == idattrib || idTarget ==
"") {
700 if (
attrib(
"id") == id_) {
706 for (
size_t i = 0; i <
nChildren(); i++) {
717 const std::string& val,
int depth)
const
720 if (
attrib(attr) == val) {
727 for (
size_t i = 0; i < n; i++) {
728 r =
m_children[i]->findByAttr(attr, val, depth - 1);
744 for (
size_t i = 0; i <
nChildren(); i++) {
761 for (
size_t i = 0; i <
nChildren(); i++) {
773 s <<
"<?xml version=\"1.0\"?>" << endl;
781 map<string, string> node_attribs;
783 node_attribs.clear();
793 if (nm[nm.size() - 1] ==
'/') {
794 nm2 = nm.substr(0,nm.size()-1);
795 node = &node->addChild(nm2);
797 node->
attribs() = node_attribs;
800 }
else if (nm[0] !=
'/') {
801 if (nm[0] !=
'!' && nm[0] !=
'-' && nm[0] !=
'?') {
802 node = &node->addChild(nm);
805 node->
attribs() = node_attribs;
807 }
else if (nm.substr(0,2) ==
"--") {
808 if (nm.substr(nm.size()-2,2) ==
"--") {
813 if (node->
name() != nm.substr(1,nm.size()-1)) {
828 map<string,string>::const_iterator b =
m_attribs.begin();
834 const vector<XML_Node*> &vsc = node_dest->
children();
840 for (
size_t idc = 0; idc < ndc; idc++) {
868 (void) node_dest->addChild(sc->
name());
884 map<string,string>::const_iterator b =
m_attribs.begin();
888 const vector<XML_Node*> &vsc = node_dest->
children();
894 (void) node_dest->addChild(sc->
name());
917 std::vector<XML_Node*>& children_)
const
919 for (
size_t i = 0; i <
nChildren(); i++) {
921 children_.push_back(&
child(i));
928 string::size_type iloc;
931 std::multimap<std::string,XML_Node*>::const_iterator i;
934 iloc = loc.find(
'/');
936 cname = loc.substr(0,iloc);
937 loc = loc.substr(iloc+1, loc.size());
940 return i->second->child(loc);
961 string indent(level,
' ');
968 s << endl << indent <<
"<!--";
973 int ll =
static_cast<int>(m_value.size()) - 1;
974 if (! isspace(m_value[ll])) {
981 s << indent <<
"<" <<
m_name;
982 map<string,string>::const_iterator b =
m_attribs.begin();
984 s <<
" " << b->first <<
"=\"" << b->second <<
"\"";
993 string::size_type ieol = vv.find(
'\n');
996 ieol = vv.find(
'\n');
999 s << endl << indent <<
" ";
1001 size_t jf = ieol - 1;
1002 for (
int j = 0; j < (int) ieol; j++) {
1003 if (! isspace(vv[j])) {
1008 s << endl << indent <<
" " << vv.substr(jf,ieol-jf);
1010 vv = vv.substr(ieol+1);
1012 int lll =
static_cast<int>(vv.size()) - 1;
1015 for (
int j = 0; j < lll; j++) {
1016 if (! isspace(vv[j])) {
1022 s << endl << indent <<
" " << vv.substr(jf);
1028 s << endl << indent;
1030 bool doSpace =
true;
1031 bool doNewLine =
false;
1032 int ll =
static_cast<int>(
m_value.size()) - 1;
1036 if (m_name ==
"floatArray") {
1044 s << endl << indent <<
" ";
1049 if (doSpace && (! isspace(
m_value[0]))) {
1057 if (doSpace && (! isspace(m_value[ll]))) {
1061 s << endl << indent;
1065 if (numRecursivesAllowed > 0) {
1068 m_children[i]->write_int(s,level + 2, numRecursivesAllowed - 1);
1072 s << endl << indent;
1074 s <<
"</" << m_name <<
">";
1082 m_children[i]->write_int(s,level, numRecursivesAllowed-1);
1086 write_int(s, level, numRecursivesAllowed);
1105 const std::string& idtarget)
1113 string rname = root->
name();
1114 if (rname ==
"phase") {
1115 if (idtarget ==
"") {
1118 idattrib = root->
id();
1119 if (idtarget == idattrib) {
1126 const vector<XML_Node*> &vsc = root->
children();
1127 for (
size_t n = 0; n < root->
nChildren(); n++) {
1129 if (sc->
name() ==
"phase") {
1130 if (idtarget ==
"") {
1133 idattrib = sc->
id();
1134 if (idtarget == idattrib) {
1139 for (
size_t n = 0; n < root->
nChildren(); n++) {
1141 if (sc->
name() !=
"phase") {
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.
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.
void setError(const std::string &r, const std::string &msg)
Set an error condition in the application class without throwing an exception.
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.
size_t m_nchildren
Number of children of this node.
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...
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, HTML_logs (see Input File Handling, Diagnostic Output, Writing messages to the screen and Writing HTML Logfiles).
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.
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.
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...
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.