1 // Copyright 2008, Google Inc. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are met: 5 // 6 // 1. Redistributions of source code must retain the above copyright notice, 7 // this list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright notice, 9 // this list of conditions and the following disclaimer in the documentation 10 // and/or other materials provided with the distribution. 11 // 3. Neither the name of Google Inc. nor the names of its contributors may be 12 // used to endorse or promote products derived from this software without 13 // specific prior written permission. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 // This file contains the declaration of the XsdFile class. 27 28 #ifndef KML_XSD_XSD_FILE_H__ 29 #define KML_XSD_XSD_FILE_H__ 30 31 #include <map> 32 #include <stack> 33 #include <vector> 34 #include "boost/scoped_ptr.hpp" 35 #include "kml/base/xmlns.h" 36 #include "kml/xsd/xsd_element.h" 37 #include "kml/xsd/xsd_complex_type.h" 38 #include "kml/xsd/xsd_schema.h" 39 #include "kml/xsd/xsd_simple_type.h" 40 #include "kml/xsd/xsd_type.h" 41 42 namespace kmlxsd { 43 44 typedef std::map<string, string> XsdAliasMap; 45 typedef std::map<string, XsdElementPtr> XsdElementMap; 46 typedef std::vector<XsdElementPtr> XsdElementVector; 47 typedef std::map<string, XsdTypePtr> XsdTypeMap; 48 typedef std::vector<XsdTypePtr> XsdTypeVector; 49 50 // This class holds the state of a processed XSD file. Overall usage: 51 // // Process: fetch and parse. 52 // const string xsd_data = fetch_the_xsd_file(); 53 // string errors; 54 // XsdFile* xsd_file = XsdFile::CreateFromParse(xsd_data, &errors); 55 // // Access XSD file info. 56 // xsd_file.GetElementNames(...); 57 // xsd_file.IsComplex(...); 58 // GetChildElementNames(...); 59 class XsdFile { 60 public: 61 static XsdFile* CreateFromParse(const string& xsd_data, 62 string* errors); 63 XsdFile()64 XsdFile() {} // Use static CreateFromParse(). 65 66 // Set <xs:schema> info. The attributes are those of the <schema> element 67 // in the XSD file. set_schema(const XsdSchemaPtr & xsd_schema)68 void set_schema(const XsdSchemaPtr& xsd_schema) { 69 xsd_schema_ = xsd_schema; 70 } 71 72 // Add global <xs:element> info. A "global" <xs:element> is a child of 73 // <xs::schema>. add_element(const XsdElementPtr & xsd_element)74 void add_element(const XsdElementPtr& xsd_element) { 75 element_map_[xsd_element->get_name()] = xsd_element; 76 } 77 78 // Add a <xs:complexType> or <xs:simpleType>. add_type(const XsdTypePtr & xsd_type)79 void add_type(const XsdTypePtr& xsd_type) { 80 type_map_[xsd_type->get_name()] = xsd_type; 81 } 82 get_target_namespace()83 const string& get_target_namespace() const { 84 return xsd_schema_->get_target_namespace(); 85 } get_target_namespace_prefix()86 const string& get_target_namespace_prefix() const { 87 return xsd_schema_->get_target_namespace_prefix(); 88 } 89 90 // Create an alias. For example, "AbstractFeatureGroup" == "Feature". set_alias(const string & real_name,const string & alias_name)91 void set_alias(const string& real_name, 92 const string& alias_name) { 93 alias_map_[real_name] = alias_name; 94 } 95 96 // Returns the alias for this name or NULL if this name has no alias. For 97 // example, if set_alias("AbstractGeometryGroup", "Geometry") was used then 98 // get_alias("AbstractGeometryGroup") returns "Geometry". get_alias(const string & real_name)99 const string get_alias(const string& real_name) const { 100 XsdAliasMap::const_iterator iter = alias_map_.find(real_name); 101 return iter == alias_map_.end() ? "" : iter->second; 102 } 103 104 // Return all <xs:element> children of <xs:schema>. Order is not preserved 105 // w.r.t. to the XSD file. 106 void GetAllElements(XsdElementVector* elements) const; 107 108 // Return all <xs:complexType> and <xs:simpleType> children of <xs:schema>. 109 // Order is not preserved w.r.t. to the XSD file. 110 void GetAllTypes(XsdTypeVector* type) const; 111 112 // Return the names of the immediate child elements of the given complex 113 // element. Each <xs:element ref="..."> is resolved. 114 void FindChildElements(const XsdComplexTypePtr& complex_element, 115 XsdElementVector* elements) const; 116 void GetChildElements(const string& complex_element_name, 117 XsdElementVector* elements) const; 118 119 120 // This looks up the given element by name. 121 const XsdElementPtr FindElement(const string& element_name) const; 122 123 // Return the XsdType for the given element. If there is no type for this 124 // element in the target namespace NULL is returned. 125 const XsdTypePtr FindElementType(const XsdElementPtr& element) const; 126 127 // This looks up the given type by name. 128 const XsdTypePtr FindType(const string& type_name) const; 129 130 // Return the global <xs:element> for the given <xs:element ref="..."/>. 131 // For example, element ref of "kml:name" returns the XsdElement describing 132 // the <xs:element name="name".../> child of <xs:schema/>. 133 const XsdElementPtr ResolveRef(const string& element_ref) const; 134 135 // Return the XsdComplexType of the complex_type's extension base. NULL is 136 // returned if the complex_type has no extension base or if the extension 137 // base is not found within this XsdFile's target namespace. 138 XsdComplexTypePtr GetBaseType(const XsdComplexTypePtr& complex_type) const; 139 140 // Return the inheritance hierarchy of a given <xs:complexType>. The first 141 // item in the vector is this type's extension base, the next that type's 142 // extension base and so on until a type with no extension base is reached. 143 bool GetTypeHierarchy(const XsdComplexTypePtr& complex_type, 144 std::vector<XsdComplexTypePtr>* type_hier) const; 145 146 // This appends all abstract elements to the given vector. 147 void GetAbstractElements(XsdElementVector* elements) const; 148 149 // This appends all concrete complex elements to the given vector. 150 void GetComplexElements(XsdElementVector* elements) const; 151 152 // This appends all concrete simple elements to the given vector. 153 void GetSimpleElements(XsdElementVector* elements) const; 154 155 // This sorts the elements in this XSD file into 3 ranges in this order and 156 // then alphabetical order within each group: 1) abstract elements, 157 // 2) complex elements, 3) simple elements. Offset 0 is reserved/invalid. 158 void GenerateElementIdVector(XsdElementVector* elements, 159 size_t* begin_complex, 160 size_t *begin_simple) const; 161 162 // If find_type is a base type of complex_type return true, else false. 163 bool SearchTypeHierarchy(const XsdComplexTypePtr& complex_type, 164 const XsdComplexTypePtr& find_type) const; 165 166 // Return all elements derived from the given complex type. 167 void GetElementsOfType(const XsdComplexTypePtr& complex_type, 168 XsdElementVector* elements) const; 169 170 // Return all elements derived from the given complex type name. 171 void GetElementsOfTypeByName(const string& type_name, 172 XsdElementVector* elements) const; 173 174 private: 175 XsdSchemaPtr xsd_schema_; 176 XsdElementMap element_map_; 177 XsdTypeMap type_map_; 178 XsdAliasMap alias_map_; 179 }; 180 181 } // end namespace kmlxsd 182 183 #endif // KML_XSD_XSD_FILE_H__ 184