OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
OtherXMLParser.cc
Go to the documentation of this file.
1 // This file is part of the "NcML Module" project, a BES module designed
3 // to allow NcML files to be used to be used as a wrapper to add
4 // AIS to existing datasets of any format.
5 //
6 // Copyright (c) 2009 OPeNDAP, Inc.
7 // Author: Michael Johnson <m.johnson@opendap.org>
8 //
9 // For more information, please also see the main website: http://opendap.org/
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26 //
27 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29 #include "NCMLDebug.h"
30 #include "NCMLParser.h"
31 #include "OtherXMLParser.h"
32 #include "XMLHelpers.h"
33 
34 namespace ncml_module
35 {
36 
37 OtherXMLParser::OtherXMLParser(NCMLParser& p)
38  : _rParser(p)
39  , _depth(0)
40  , _otherXML("")
41 {
42 }
43 
45 {
46  reset(); // for consistency
47 }
48 
49 int
51 {
52  return _depth;
53 }
54 
55 
56 const std::string&
58 {
59  return _otherXML;
60 }
61 
62 void
64 {
65  _depth = 0;
66  _otherXML = "";
67 }
68 
69 void
71 {
72  THROW_NCML_INTERNAL_ERROR("OtherXMLParser::onStartDocument called! This is a logic bug.");
73 }
74 
75 void
77 {
78  THROW_NCML_INTERNAL_ERROR("OtherXMLParser::onEndDocument called! This is a logic bug.");
79 }
80 
81 void
82 OtherXMLParser::onStartElement(const std::string& name, const XMLAttributeMap& attrs)
83 {
84  appendOpenStartElementTag(name, "");
85  appendAttributes(attrs);
86  // no namespaces for this set of calls... presumably in the attributes
87  appendCloseStartElementTag();
88 
89  pushDepth();
90 }
91 
92 void
93 OtherXMLParser::onEndElement(const std::string& name)
94 {
95  appendEndElementTag(name);
96  popDepth();
97 }
98 
99 void
101  const std::string& localname,
102  const std::string& prefix,
103  const std::string& /* uri */,
104  const XMLAttributeMap& attributes,
105  const XMLNamespaceMap& namespaces)
106 {
107  appendOpenStartElementTag(localname, prefix);
108  appendAttributes(attributes);
109 
110  // if a root element, grab ALL the namespaces from the parents since we will be
111  // disconnected from them and will lose the namespaces if not
112  if (_depth == 0)
113  {
114  BESDEBUG("ncml", "Got depth 0 OtherXML element while parsing OtherXML attribute..." <<
115  " Pulling all un-shadowed ancestral namespaces into the element with localname=" <<
116  localname << endl);
117 
118  // initialize it with the local node namespaces, since they
119  // take precedence over the stack
120  XMLNamespaceMap ancestralNamespaces(namespaces);
121  // then fill in the rest from the current stack
122  _rParser.getXMLNamespaceStack().getFlattenedNamespacesUsingLexicalScoping(ancestralNamespaces);
123  appendNamespaces(ancestralNamespaces);
124  }
125  else // Append the ones local to JUST this element if not root
126  {
127  appendNamespaces(namespaces);
128  }
129 
130  appendCloseStartElementTag();
131 
132  pushDepth();
133 }
134 
135 void
137  const std::string& localname,
138  const std::string& prefix,
139  const std::string& /*uri*/)
140 {
141  appendEndElementTag(XMLAttribute::getQName(prefix, localname));
142  popDepth();
143 }
144 
145 void
146 OtherXMLParser::onCharacters(const std::string& content)
147 {
148  // Really just shove them on there, whitespace and all to maintain formatting I guess. Does this do that?
149  _otherXML.append(content);
150 }
151 
152 void
154 {
155  THROW_NCML_PARSE_ERROR(-1, // the SAX errors have the line in there already
156  "OtherXMLParser: got SAX parse warning while parsing OtherXML. Msg was: " + msg);
157 }
158 
159 void
161 {
163  "OtherXMLParser: got SAX parse error while parsing OtherXML. Msg was: " + msg);
164 }
165 
166 void
167 OtherXMLParser::appendOpenStartElementTag(const std::string& localname, const std::string& prefix)
168 {
169  // Append this element and all its attributes onto the string
170  _otherXML += string("<");
171  _otherXML += XMLAttribute::getQName(prefix, localname);
172 }
173 
174 void
175 OtherXMLParser::appendAttributes(const XMLAttributeMap& attributes)
176 {
177  for (XMLAttributeMap::const_iterator it = attributes.begin();
178  it != attributes.end();
179  ++it)
180  {
181  _otherXML += ( string(" ") +
182  it->getQName() +
183  "=\"" +
184  it->value +
185  "\"" );
186  }
187 }
188 
189 void
190 OtherXMLParser::appendNamespaces(const XMLNamespaceMap& namespaces)
191 {
192  _otherXML += namespaces.getAllNamespacesAsAttributeString();
193 }
194 
195 void
196 OtherXMLParser::appendCloseStartElementTag()
197 {
198  _otherXML += ">";
199 }
200 
201 void
202 OtherXMLParser::appendEndElementTag(const string& qname)
203 {
204  _otherXML += ( string("</") + qname + ">" );
205 }
206 
207 void
208 OtherXMLParser::pushDepth()
209 {
210  ++_depth;
211 }
212 
213 void
214 OtherXMLParser::popDepth()
215 {
216  --_depth;
217 
218  // Check for underflow
219  if (_depth < 0)
220  {
221  // I am not sure this is internal or user can cause it... making it internal for now...
222  THROW_NCML_INTERNAL_ERROR("OtherXMLElement::onEndElement: _depth < 0! Logic error in parsing OtherXML.");
223  }
224 }
225 
226 
227 } // namespace ncml_module
int getParseDepth() const
Get the current parse depth (how many elements we've opened with onStartElement and not closed yet) I...
virtual void onParseWarning(std::string msg)
A recoverable parse error occured.
An abstract superclass for NCMLArray that handles the non-parameterized functionality and allows u...
virtual void onEndElementWithNamespace(const std::string &localname, const std::string &prefix, const std::string &uri)
SAX2 End element with namespace information.
const XMLNamespaceStack & getXMLNamespaceStack() const
If using namespaces, get the current stack of namespaces.
Definition: NCMLParser.cc:228
virtual void onStartElement(const std::string &name, const XMLAttributeMap &attrs)
const std::string & getString() const
Get the parsed data as big string that we've been parsing in.
virtual void onCharacters(const std::string &content)
Called when characters are encountered within an element.
#define THROW_NCML_PARSE_ERROR(parseLine, msg)
Definition: NCMLDebug.h:69
void getFlattenedNamespacesUsingLexicalScoping(XMLNamespaceMap &nsFlattened) const
Scanning from the stack top downwards, add the first found new XMLNamespace (in terms of its prefix) ...
Definition: XMLHelpers.cc:539
#define THROW_NCML_INTERNAL_ERROR(msg)
Definition: NCMLDebug.h:61
vector< XMLAttribute >::const_iterator const_iterator
Definition: XMLHelpers.h:104
void reset()
Reset the string and depth so we can start parsing from scratch again.
virtual void onStartElementWithNamespace(const std::string &localname, const std::string &prefix, const std::string &uri, const XMLAttributeMap &attributes, const XMLNamespaceMap &namespaces)
SAX2 start element call with gets namespace information.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
virtual void onEndElement(const std::string &name)
string getQName() const
get the name with the prefix:localname if prefix not empty else localname
Definition: XMLHelpers.cc:129
virtual void onParseError(std::string msg)
An unrecoverable parse error occurred.