Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_XMLObjectImplem.cpp
1// @HEADER
2// *****************************************************************************
3// Teuchos: Common Tools Package
4//
5// Copyright 2004 NTESS and the Teuchos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teuchos_XMLObject.hpp"
11#include "Teuchos_StrUtils.hpp"
12#include <cstring>
13
14using namespace Teuchos;
15
16
18 : tag_(tag), attributes_(), children_(0), content_(0)
19{;}
20
22{
24 TEUCHOS_TEST_FOR_EXCEPTION(rtn==0, std::runtime_error, "XMLObjectImplem::deepCopy()");
25 rtn->attributes_ = attributes_;
26 rtn->content_ = content_;
27
28 for (int i=0; i<children_.length(); i++)
29 {
30 rtn->addChild(children_[i].deepCopy());
31 }
32
33 return rtn;
34}
35
37{
38 return children_.length();
39}
40
41void XMLObjectImplem::addAttribute(const std::string& name,
42 const std::string& value)
43{
44 attributes_[name] = value;
45}
46
48{
49 children_.append(child);
50}
51
53{
54 content_.append(contentLine);
55}
56
58{
60 // does bound checking within content_.erase if BoundaryChecks are enabled
61 content_.erase(pos);
62}
63
65{
66 return children_[i];
67}
68
69std::string XMLObjectImplem::header(bool strictXML) const
70{
71 std::string rtn = "<" + tag_;
72 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
73 {
74 if (strictXML)
75 {
76 rtn += " "
77 + (*i).first
78 + "="
79 + XMLifyAttVal((*i).second);
80 }
81 else
82 {
83 rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
84 }
85 }
86
87 rtn += ">";
88 return rtn;
89}
90
91std::string XMLObjectImplem::XMLifyAttVal(const std::string &attval) {
92 std::string ret;
93 bool hasQuot, hasApos;
94 char delim;
95
96 if (attval.find("\"") == std::string::npos)
97 {
98 hasQuot = false;
99 }
100 else
101 {
102 hasQuot = true;
103 }
104
105 if (attval.find("\'") == std::string::npos)
106 {
107 hasApos = false;
108 }
109 else
110 {
111 hasApos = true;
112 }
113
114 if (!hasQuot || hasApos)
115 {
116 delim = '\"'; // wrap the attribute value in "
117 }
118 else
119 {
120 delim = '\''; // wrap the attribute value in '
121 }
122
123 // Rules:
124 // "-wrapped std::string cannot contain a literal "
125 // '-wrapped std::string cannot contain a literal '
126 // attribute value cannot contain a literal <
127 // attribute value cannot contain a literal &
128 ret.push_back(delim);
129 for (std::string::const_iterator i=attval.begin(); i != attval.end(); i++)
130 {
131 if (*i == delim)
132 {
133 if (delim == '\'') ret.append("&apos;");
134 else if (delim == '\"') ret.append("&quot;");
135 }
136 else if (*i == '&')
137 {
138 ret.append("&amp;");
139 }
140 else if (*i == '<')
141 {
142 ret.append("&lt;");
143 }
144 else
145 {
146 ret.push_back(*i);
147 }
148 }
149 ret.push_back(delim);
150
151 return ret;
152}
153
155{
156 std::string rtn = "<" + tag_;
157 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
158 {
159 if (strictXML)
160 {
161 rtn += " "
162 + (*i).first
163 + "="
164 + XMLifyAttVal((*i).second);
165 }
166 else
167 {
168 rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
169 }
170 }
171
172 rtn += "/>";
173 return rtn;
174}
175
176std::string XMLObjectImplem::toString() const
177{
178 std::string rtn;
179 if (content_.length()==0 && children_.length()==0)
180 {
181 rtn = terminatedHeader(true) + "\n";
182 }
183 else
184 {
185 rtn = header() + "\n";
186 bool allBlankContent = true;
187 for (int i=0; i<content_.length(); i++)
188 {
189 if (!StrUtils::isWhite(content_[i]))
190 {
191 allBlankContent=false;
192 break;
193 }
194 }
195 if (!allBlankContent)
196 {
197 for (int i=0; i<content_.length(); i++)
198 {
199 rtn += content_[i];
200 }
201 rtn += "\n";
202 }
203 for (int i=0; i<children_.length(); i++)
204 {
205 rtn += children_[i].toString();
206 }
207 rtn += "</" + tag_ + ">\n";
208 }
209 return rtn;
210}
211
212void XMLObjectImplem::print(std::ostream& os, int indent) const
213{
214 for (int i=0; i<indent; i++) os << " ";
215 if (content_.length()==0 && children_.length()==0)
216 {
217 os << terminatedHeader(true) << std::endl;
218 return;
219 }
220 else
221 {
222 os << header(true) << std::endl;
223 printContent(os, indent+2);
224
225 for (int i=0; i<children_.length(); i++)
226 {
227 children_[i].print(os, indent+2);
228 }
229 for (int i=0; i<indent; i++) os << " ";
230 os << "</" << tag_ << ">\n";
231 }
232}
233
234void XMLObjectImplem::printContent(std::ostream& os, int indent) const
235{
236 std::string space = "";
237 for (int i=0; i<indent; i++) space += " ";
238
239 bool allBlankContent = true;
240 for (int i=0; i<content_.length(); i++)
241 {
242 if (!StrUtils::isWhite(content_[i]))
243 {
244 allBlankContent=false;
245 break;
246 }
247 }
248
249 if (!allBlankContent)
250 {
251
252 for (int i=0; i<content_.length(); i++)
253 {
254 // remove leading spaces, we will indent
255 std::string s(content_[i]);
256 s.erase(size_t(0), s.find_first_not_of(" \r\t"));
257 if((s.length()>0) && (!StrUtils::isWhite(s)))
258 os << space << s << '\n';
259 }
260 }
261}
262
A std::string utilities class for Teuchos.
An object representation of a subset of XML data.
int length() const
Return number of elements in the array.
std::vector< T >::iterator iterator
The type of a forward iterator.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
iterator erase(iterator position)
Smart reference counting pointer class for automatic garbage collection.
static bool isWhite(const std::string &str)
Returns true if a std::string consists entirely of whitespace.
The XMLObjectImplem class takes care of the low-level implementation details of XMLObject.
int numChildren() const
Return the number of children.
std::string terminatedHeader(bool strictXML=false) const
Write the header terminated as <Header>
XMLObjectImplem * deepCopy() const
Deep copy.
const XMLObject & getChild(int i) const
Look up a child by its index.
void addAttribute(const std::string &name, const std::string &value)
Add a [name, value] attribute.
void removeContentLine(const size_t &i)
Remove content line by index.
void addContent(const std::string &contentLine)
Add a content line.
XMLObjectImplem(const std::string &tag)
Construct with a 'tag'.
std::string header(bool strictXML=false) const
Write the header.
void addChild(const XMLObject &child)
Add a child XMLObject.
std::string toString() const
Write as a std::string. Output may be ill-formed XML.
void print(std::ostream &os, int indent) const
Print to stream with the given indentation level. Output will be well-formed XML.
Representation of an XML data tree. XMLObject is a ref-counted handle to a XMLObjectImplem object,...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...