Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Teuchos_XMLObjectImplem.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Teuchos: Common Tools Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42#include "Teuchos_XMLObject.hpp"
43#include "Teuchos_StrUtils.hpp"
44#include <cstring>
45
46using namespace Teuchos;
47
48
49XMLObjectImplem::XMLObjectImplem(const std::string& tag)
50 : tag_(tag), attributes_(), children_(0), content_(0)
51{;}
52
54{
56 TEUCHOS_TEST_FOR_EXCEPTION(rtn==0, std::runtime_error, "XMLObjectImplem::deepCopy()");
58 rtn->content_ = content_;
59
60 for (int i=0; i<children_.length(); i++)
61 {
62 rtn->addChild(children_[i].deepCopy());
63 }
64
65 return rtn;
66}
67
69{
70 return children_.length();
71}
72
73void XMLObjectImplem::addAttribute(const std::string& name,
74 const std::string& value)
75{
76 attributes_[name] = value;
77}
78
80{
81 children_.append(child);
82}
83
84void XMLObjectImplem::addContent(const std::string& contentLine)
85{
86 content_.append(contentLine);
87}
88
90{
92 // does bound checking within content_.erase if BoundaryChecks are enabled
93 content_.erase(pos);
94}
95
97{
98 return children_[i];
99}
100
101std::string XMLObjectImplem::header(bool strictXML) const
102{
103 std::string rtn = "<" + tag_;
104 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
105 {
106 if (strictXML)
107 {
108 rtn += " "
109 + (*i).first
110 + "="
111 + XMLifyAttVal((*i).second);
112 }
113 else
114 {
115 rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
116 }
117 }
118
119 rtn += ">";
120 return rtn;
121}
122
123std::string XMLObjectImplem::XMLifyAttVal(const std::string &attval) {
124 std::string ret;
125 bool hasQuot, hasApos;
126 char delim;
127
128 if (attval.find("\"") == std::string::npos)
129 {
130 hasQuot = false;
131 }
132 else
133 {
134 hasQuot = true;
135 }
136
137 if (attval.find("\'") == std::string::npos)
138 {
139 hasApos = false;
140 }
141 else
142 {
143 hasApos = true;
144 }
145
146 if (!hasQuot || hasApos)
147 {
148 delim = '\"'; // wrap the attribute value in "
149 }
150 else
151 {
152 delim = '\''; // wrap the attribute value in '
153 }
154
155 // Rules:
156 // "-wrapped std::string cannot contain a literal "
157 // '-wrapped std::string cannot contain a literal '
158 // attribute value cannot contain a literal <
159 // attribute value cannot contain a literal &
160 ret.push_back(delim);
161 for (std::string::const_iterator i=attval.begin(); i != attval.end(); i++)
162 {
163 if (*i == delim)
164 {
165 if (delim == '\'') ret.append("&apos;");
166 else if (delim == '\"') ret.append("&quot;");
167 }
168 else if (*i == '&')
169 {
170 ret.append("&amp;");
171 }
172 else if (*i == '<')
173 {
174 ret.append("&lt;");
175 }
176 else
177 {
178 ret.push_back(*i);
179 }
180 }
181 ret.push_back(delim);
182
183 return ret;
184}
185
186std::string XMLObjectImplem::terminatedHeader(bool strictXML) const
187{
188 std::string rtn = "<" + tag_;
189 for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
190 {
191 if (strictXML)
192 {
193 rtn += " "
194 + (*i).first
195 + "="
196 + XMLifyAttVal((*i).second);
197 }
198 else
199 {
200 rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
201 }
202 }
203
204 rtn += "/>";
205 return rtn;
206}
207
208std::string XMLObjectImplem::toString() const
209{
210 std::string rtn;
211 if (content_.length()==0 && children_.length()==0)
212 {
213 rtn = terminatedHeader(true) + "\n";
214 }
215 else
216 {
217 rtn = header() + "\n";
218 bool allBlankContent = true;
219 for (int i=0; i<content_.length(); i++)
220 {
222 {
223 allBlankContent=false;
224 break;
225 }
226 }
227 if (!allBlankContent)
228 {
229 for (int i=0; i<content_.length(); i++)
230 {
231 rtn += content_[i];
232 }
233 rtn += "\n";
234 }
235 for (int i=0; i<children_.length(); i++)
236 {
237 rtn += children_[i].toString();
238 }
239 rtn += "</" + tag_ + ">\n";
240 }
241 return rtn;
242}
243
244void XMLObjectImplem::print(std::ostream& os, int indent) const
245{
246 for (int i=0; i<indent; i++) os << " ";
247 if (content_.length()==0 && children_.length()==0)
248 {
249 os << terminatedHeader(true) << std::endl;
250 return;
251 }
252 else
253 {
254 os << header(true) << std::endl;
255 printContent(os, indent+2);
256
257 for (int i=0; i<children_.length(); i++)
258 {
259 children_[i].print(os, indent+2);
260 }
261 for (int i=0; i<indent; i++) os << " ";
262 os << "</" << tag_ << ">\n";
263 }
264}
265
266void XMLObjectImplem::printContent(std::ostream& os, int indent) const
267{
268 std::string space = "";
269 for (int i=0; i<indent; i++) space += " ";
270
271 bool allBlankContent = true;
272 for (int i=0; i<content_.length(); i++)
273 {
275 {
276 allBlankContent=false;
277 break;
278 }
279 }
280
281 if (!allBlankContent)
282 {
283
284 for (int i=0; i<content_.length(); i++)
285 {
286 // remove leading spaces, we will indent
287 std::string s(content_[i]);
288 s.erase(size_t(0), s.find_first_not_of(" \r\t"));
289 if((s.length()>0) && (!StrUtils::isWhite(s)))
290 os << space << s << '\n';
291 }
292 }
293}
294
A std::string utilities class for Teuchos.
An object representation of a subset of XML data.
iterator begin()
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)
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>
void printContent(std::ostream &os, int indent) const
Print content lines using the given indentation level.
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.
static std::string XMLifyAttVal(const std::string &attval)
Convert attribute value text into well-formed XML.
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.