00001
00002 #ifndef MiX_XPath_h_
00003 #define MiX_XPath_h_
00004
00005 #include "misc.h"
00006 #include "classes.h"
00007
00008 namespace MiX {
00009 enum ResultType{
00010 Result_Null = 0,
00011 Result_NodeList,
00012 Result_Element = Result_NodeList,
00013 Result_Boolean,
00014 Result_Number,
00015 Result_String
00016 };
00017
00018 template <class charT, class char_traits,class xml_traits>
00019 class XPathException : public std::exception{
00020 public:
00021 MiX_Template_Typedef(charT,char_traits,xml_traits);
00022 private:
00023 ErrorType type_;
00024 std::string what_;
00025 public:
00026 XPathException( ErrorType type, const std::string& what )
00027 : type_(type), what_(what) { }
00028 ~XPathException() throw() { }
00029 const char* what() const throw() { return what_.c_str(); }
00030 ErrorType getType() const throw() { return type_; }
00031 };
00032
00033 template <class charT, class char_traits,class xml_traits>
00034 class XPathResult {
00035 public:
00036 MiX_Template_Typedef(charT, char_traits, xml_traits );
00037 private:
00038 union {
00039 void* ptr_;
00040 nodelist_type* list_;
00041 bool* bool_;
00042 double* number_;
00043 string_type* str_;
00044 };
00045 ResultType type_;
00046 public:
00047 void assign( const xpathresult_type& src );
00048 void clear();
00049 XPathResult() : type_(Result_Null), ptr_(0) { }
00050
00051 XPathResult( const nodelist_type& src ) : type_(Result_NodeList) {
00052 list_ = new nodelist_type();
00053 typename nodelist_type::const_iterator it = src.begin();
00054 typename nodelist_type::const_iterator last = src.end();
00055 for( ; it!=last ; ++it ) {
00056 list_->push_back( *it );
00057 }
00058 }
00059 XPathResult( bool src ) : type_(Result_Boolean), bool_(new bool(src)) { }
00060 XPathResult( double src ) : type_(Result_Number), number_(new double(src)) { }
00061 XPathResult( const string_type& src ) : type_(Result_String), str_(new string_type(src)) { }
00062 XPathResult( const xpathresult_type& src ) { assign( src ); }
00063 virtual ~XPathResult() { clear(); }
00064 xpathresult_type& operator=( const xpathresult_type& src ) {
00065 clear( );
00066 assign( src );
00067 }
00068 ResultType getType() const { return type_; };
00070 nodelist_type& getNodeList() { return *list_; }
00071 const nodelist_type& getNodeList() const { return *list_; }
00072 element_type& getElement() {
00073 typename nodelist_type::iterator it = list_->begin();
00074 typename nodelist_type::iterator last = list_->end();
00075 return dynamic_cast<element_type&>( **(list_->begin()) );
00076 }
00077 const element_type& getElement() const {
00078 return dynamic_cast<const element_type&>( **(list_->begin()) );
00079 }
00080 bool getBoolean() const { return *bool_; }
00081 double getNumber() const { return *number_; }
00082 string_type& getString() { return *str_; }
00083 const string_type& getString() const { return *str_; }
00084 void output( std::ostream& os ) const;
00085 };
00086
00087 template <class charT, class char_traits,class xml_traits>
00088 std::ostream& operator << ( std::ostream& os, const XPathResult<charT,char_traits,xml_traits>& obj ) {
00089 obj.output( os ); return os;
00090 }
00091
00095 template <class charT, class char_traits,class xml_traits>
00096 class XPath {
00097 public:
00098 MiX_Template_Typedef(charT, char_traits, xml_traits );
00099 private:
00100 std::list<xpathatom_type*> atoms_;
00101 public:
00102 XPath( const string_type& src );
00103 virtual ~XPath() throw();
00104 xpathresult_type operator() ( nodecontainer_type& el ) { return execute(el); }
00105 xpathresult_type execute( nodecontainer_type& el );
00106 };
00107 }
00108
00109 #ifndef MiX_XPath_cpp_
00110 #include "XPath.cpp"
00111 #endif
00112
00113 #endif