contrib/brl/bbas/bxml/bxml_document.h
Go to the documentation of this file.
00001 // This is brl/bbas/bxml/bxml_document.h
00002 #ifndef bxml_document_h_
00003 #define bxml_document_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief An XML document representation
00010 // \author Matt Leotta (Brown)
00011 // \date   October 5, 2006
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   Ozge C. Ozcanli (Brown) - July 15, 2009 - enabled smart pointer for bxml_document
00016 //   Ricardo Fabbri (Brown) - October 18, 2009 - specialized get_attribute for strings
00017 // \endverbatim
00018 
00019 #include <vcl_string.h>
00020 #include <vcl_sstream.h>
00021 #include <vcl_map.h>
00022 #include <vcl_vector.h>
00023 #include <vbl/vbl_ref_count.h>
00024 #include <vbl/vbl_smart_ptr.h>
00025 #include <vsl/vsl_binary_io.h>
00026 
00027 //: A block of character data found within XML tags
00028 // This is a base class and can be either plain text or
00029 // an XML element
00030 class bxml_data : public vbl_ref_count
00031 {
00032  public:
00033   enum datatype {TEXT, ELEMENT};
00034 
00035   virtual ~bxml_data() {}
00036 
00037   //: Return the type of XML data
00038   virtual datatype type() const = 0;
00039 };
00040 
00041 //: compare two XML data objects
00042 bool operator==(const bxml_data& d1, const bxml_data& d2);
00043 
00044 
00045 typedef vbl_smart_ptr<bxml_data> bxml_data_sptr;
00046 
00047 
00048 //: text data within XML
00049 class bxml_text : public bxml_data
00050 {
00051  public:
00052   //: Constructor
00053   bxml_text(const vcl_string& data) : data_(data) {}
00054 
00055   //: Destructor
00056   virtual ~bxml_text() {}
00057 
00058   //: Return the type of XML data
00059   datatype type() const { return TEXT; }
00060 
00061   //: Access the text data
00062   vcl_string data() const { return data_; }
00063 
00064   //: Set the text data
00065   void set_data(const vcl_string& data) { data_ = data; }
00066 
00067  private:
00068   vcl_string data_;
00069 };
00070 
00071 
00072 //: An XML element
00073 class bxml_element : public bxml_data
00074 {
00075  public:
00076   typedef vcl_vector<bxml_data_sptr>::const_iterator const_data_iterator;
00077   typedef vcl_map<vcl_string,vcl_string>::const_iterator const_attr_iterator;
00078 
00079   //: Constructor - default
00080   bxml_element() {}
00081 
00082   //: Constructor
00083   bxml_element(const vcl_string& name) : name_(name) {}
00084 
00085   //: Destructor
00086   virtual ~bxml_element() {}
00087 
00088   //: Return the type of XML data
00089   datatype type() const { return ELEMENT; }
00090 
00091   //: Return the name of the element
00092   vcl_string name() const { return name_; }
00093 
00094   //: Return the value of an attribute
00095   vcl_string attribute(const vcl_string& attr_name) const;
00096 
00097   //: Specialization for vcl_string.
00098   bool get_attribute(const vcl_string& attr_name, vcl_string& value) const
00099   {
00100     value = this->attribute(attr_name);
00101     return true;
00102   }
00103 
00104   //: Return the value of an attribute.
00105   // \see specialization for vcl_string.
00106   template <class T>
00107   bool get_attribute(const vcl_string& attr_name, T& value) const
00108   {
00109     vcl_stringstream s(this->attribute(attr_name));
00110     if (s.str() == "")
00111       return false;
00112     s >> value;
00113     return true;
00114   }
00115   
00116   
00117   //: Return the values of all attributes with a given name
00118   vcl_vector<vcl_string> attributes(const vcl_string& attr_name) const;
00119   
00120   //: Specialization for vcl_string.
00121   bool get_attributea(const vcl_string& attr_name, vcl_vector<vcl_string>& values) const
00122   {
00123     values = this->attributes(attr_name);
00124     return true;
00125   }
00126   
00127   //: Return the value of an attribute.
00128   // \see specialization for vcl_string.
00129   template <class T>
00130   bool get_attributes(const vcl_string& attr_name, vcl_vector<T>& values) const
00131   {
00132     values.clear();
00133     vcl_vector<vcl_string> values_str = attributes(attr_name);
00134     for (unsigned vi=0; vi<values_str.size(); vi++) {
00135       vcl_stringstream s(values_str[vi]);
00136       if (s.str() == "")
00137         return false;
00138       T value_t;
00139       s >> value_t;
00140       values.push_back(value_t);
00141       
00142     }
00143     return true;
00144   }
00145 
00146   //: Return the number of attributes
00147   unsigned int num_attributes() const { return (unsigned int)attributes_.size(); }
00148 
00149   //: An iterator to the beginning of the attributes
00150   const_attr_iterator attr_begin() const { return attributes_.begin(); }
00151 
00152   //: An iterator to the end of the attributes
00153   const_attr_iterator attr_end() const { return attributes_.end(); }
00154 
00155   //: Return the number of data nodes
00156   unsigned int num_data() const { return (unsigned int)data_.size(); }
00157 
00158   //: An iterator to the beginning of the data
00159   const_data_iterator data_begin() const { return data_.begin(); }
00160 
00161   //: An iterator to the end of the data
00162   const_data_iterator data_end() const { return data_.end(); }
00163 
00164   //: Append text in this element
00165   void append_text(const vcl_string& text);
00166 
00167   //: Append data (typically another element) in this element
00168   void append_data(const bxml_data_sptr& el)
00169   { data_.push_back(el); }
00170 
00171   //: Set attribute with and optional precision.
00172   template <class T>
00173   void set_attribute(const vcl_string& attr_name, const T& attr_value, unsigned p = 5)
00174   {
00175     vcl_stringstream s;
00176     s.precision(p);
00177     s << attr_value;
00178     attributes_[attr_name] = s.str();
00179   }
00180   //: Specialization for vcl_string below.
00181   void set_attribute(const vcl_string& attr_name, const vcl_string& attr_value)
00182   { attributes_[attr_name] = attr_value; }
00183 
00184  private:
00185   //: The name of the element
00186   vcl_string name_;
00187 
00188   //: The map of attributes to values
00189   vcl_map<vcl_string,vcl_string> attributes_;
00190 
00191   //: The character data.
00192   vcl_vector<bxml_data_sptr> data_;
00193 };
00194 
00195 
00196 //: compare two XML element objects
00197 bool operator==(const bxml_element& e1, const bxml_element& e2);
00198 
00199 
00200 //: Represents a full XML document stored as a tree
00201 class bxml_document : public vbl_ref_count
00202 {
00203  public:
00204   //: Constructor - default
00205   bxml_document();
00206 
00207   //: Destructor
00208   ~bxml_document(){}
00209 
00210   //: Return the root element
00211   bxml_data_sptr root_element() const {return root_element_;}
00212 
00213   //: Return the version string
00214   vcl_string version() const { return version_; }
00215 
00216   //: Return the encoding string
00217   vcl_string encoding() const { return encoding_; }
00218 
00219   //: Return the standalone bit
00220   bool standalone() const { return standalone_; }
00221 
00222   //: set the root element
00223   void set_root_element(const bxml_data_sptr& root)
00224   { root_element_ = root; }
00225 
00226   //: Set the version string
00227   void set_version(const vcl_string& version) { version_ = version; }
00228 
00229   //: Set the encoding string
00230   void set_encoding(const vcl_string& encoding) { encoding_ = encoding; }
00231 
00232   //: Set the standalone bit
00233   void set_standalone(bool standalone) { standalone_ = standalone; }
00234 
00235  private:
00236   //: The root element
00237   bxml_data_sptr root_element_;
00238 
00239   vcl_string version_;
00240   vcl_string encoding_;
00241   bool standalone_;
00242 };
00243 
00244 
00245 
00246 typedef vbl_smart_ptr<bxml_document> bxml_document_sptr;
00247 
00248 //: compare two XML documents
00249 bool operator==(const bxml_document& d1, const bxml_document& d2);
00250 
00251 // Binary io, NOT IMPLEMENTED, signatures defined to use bxml_document as a brdb_value
00252 void vsl_b_write(vsl_b_ostream & os, bxml_document const &ph);
00253 void vsl_b_read(vsl_b_istream & is, bxml_document &ph);
00254 void vsl_b_read(vsl_b_istream& is, bxml_document* ph);
00255 void vsl_b_write(vsl_b_ostream& os, const bxml_document* &ph);
00256 
00257 
00258 #endif // bxml_document_h_