You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
7.6 KiB
C
184 lines
7.6 KiB
C
2 years ago
|
// Copyright 2008, Google Inc. All rights reserved.
|
||
|
//
|
||
|
// Redistribution and use in source and binary forms, with or without
|
||
|
// modification, are permitted provided that the following conditions are met:
|
||
|
//
|
||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||
|
// this list of conditions and the following disclaimer.
|
||
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||
|
// this list of conditions and the following disclaimer in the documentation
|
||
|
// and/or other materials provided with the distribution.
|
||
|
// 3. Neither the name of Google Inc. nor the names of its contributors may be
|
||
|
// used to endorse or promote products derived from this software without
|
||
|
// specific prior written permission.
|
||
|
//
|
||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||
|
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||
|
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||
|
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
|
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
|
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||
|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
// This file contains the declaration of the XsdFile class.
|
||
|
|
||
|
#ifndef KML_XSD_XSD_FILE_H__
|
||
|
#define KML_XSD_XSD_FILE_H__
|
||
|
|
||
|
#include <map>
|
||
|
#include <stack>
|
||
|
#include <vector>
|
||
|
#include "boost/scoped_ptr.hpp"
|
||
|
#include "kml/base/xmlns.h"
|
||
|
#include "kml/xsd/xsd_element.h"
|
||
|
#include "kml/xsd/xsd_complex_type.h"
|
||
|
#include "kml/xsd/xsd_schema.h"
|
||
|
#include "kml/xsd/xsd_simple_type.h"
|
||
|
#include "kml/xsd/xsd_type.h"
|
||
|
|
||
|
namespace kmlxsd {
|
||
|
|
||
|
typedef std::map<string, string> XsdAliasMap;
|
||
|
typedef std::map<string, XsdElementPtr> XsdElementMap;
|
||
|
typedef std::vector<XsdElementPtr> XsdElementVector;
|
||
|
typedef std::map<string, XsdTypePtr> XsdTypeMap;
|
||
|
typedef std::vector<XsdTypePtr> XsdTypeVector;
|
||
|
|
||
|
// This class holds the state of a processed XSD file. Overall usage:
|
||
|
// // Process: fetch and parse.
|
||
|
// const string xsd_data = fetch_the_xsd_file();
|
||
|
// string errors;
|
||
|
// XsdFile* xsd_file = XsdFile::CreateFromParse(xsd_data, &errors);
|
||
|
// // Access XSD file info.
|
||
|
// xsd_file.GetElementNames(...);
|
||
|
// xsd_file.IsComplex(...);
|
||
|
// GetChildElementNames(...);
|
||
|
class XsdFile {
|
||
|
public:
|
||
|
static XsdFile* CreateFromParse(const string& xsd_data,
|
||
|
string* errors);
|
||
|
|
||
|
XsdFile() {} // Use static CreateFromParse().
|
||
|
|
||
|
// Set <xs:schema> info. The attributes are those of the <schema> element
|
||
|
// in the XSD file.
|
||
|
void set_schema(const XsdSchemaPtr& xsd_schema) {
|
||
|
xsd_schema_ = xsd_schema;
|
||
|
}
|
||
|
|
||
|
// Add global <xs:element> info. A "global" <xs:element> is a child of
|
||
|
// <xs::schema>.
|
||
|
void add_element(const XsdElementPtr& xsd_element) {
|
||
|
element_map_[xsd_element->get_name()] = xsd_element;
|
||
|
}
|
||
|
|
||
|
// Add a <xs:complexType> or <xs:simpleType>.
|
||
|
void add_type(const XsdTypePtr& xsd_type) {
|
||
|
type_map_[xsd_type->get_name()] = xsd_type;
|
||
|
}
|
||
|
|
||
|
const string& get_target_namespace() const {
|
||
|
return xsd_schema_->get_target_namespace();
|
||
|
}
|
||
|
const string& get_target_namespace_prefix() const {
|
||
|
return xsd_schema_->get_target_namespace_prefix();
|
||
|
}
|
||
|
|
||
|
// Create an alias. For example, "AbstractFeatureGroup" == "Feature".
|
||
|
void set_alias(const string& real_name,
|
||
|
const string& alias_name) {
|
||
|
alias_map_[real_name] = alias_name;
|
||
|
}
|
||
|
|
||
|
// Returns the alias for this name or NULL if this name has no alias. For
|
||
|
// example, if set_alias("AbstractGeometryGroup", "Geometry") was used then
|
||
|
// get_alias("AbstractGeometryGroup") returns "Geometry".
|
||
|
const string get_alias(const string& real_name) const {
|
||
|
XsdAliasMap::const_iterator iter = alias_map_.find(real_name);
|
||
|
return iter == alias_map_.end() ? "" : iter->second;
|
||
|
}
|
||
|
|
||
|
// Return all <xs:element> children of <xs:schema>. Order is not preserved
|
||
|
// w.r.t. to the XSD file.
|
||
|
void GetAllElements(XsdElementVector* elements) const;
|
||
|
|
||
|
// Return all <xs:complexType> and <xs:simpleType> children of <xs:schema>.
|
||
|
// Order is not preserved w.r.t. to the XSD file.
|
||
|
void GetAllTypes(XsdTypeVector* type) const;
|
||
|
|
||
|
// Return the names of the immediate child elements of the given complex
|
||
|
// element. Each <xs:element ref="..."> is resolved.
|
||
|
void FindChildElements(const XsdComplexTypePtr& complex_element,
|
||
|
XsdElementVector* elements) const;
|
||
|
void GetChildElements(const string& complex_element_name,
|
||
|
XsdElementVector* elements) const;
|
||
|
|
||
|
|
||
|
// This looks up the given element by name.
|
||
|
const XsdElementPtr FindElement(const string& element_name) const;
|
||
|
|
||
|
// Return the XsdType for the given element. If there is no type for this
|
||
|
// element in the target namespace NULL is returned.
|
||
|
const XsdTypePtr FindElementType(const XsdElementPtr& element) const;
|
||
|
|
||
|
// This looks up the given type by name.
|
||
|
const XsdTypePtr FindType(const string& type_name) const;
|
||
|
|
||
|
// Return the global <xs:element> for the given <xs:element ref="..."/>.
|
||
|
// For example, element ref of "kml:name" returns the XsdElement describing
|
||
|
// the <xs:element name="name".../> child of <xs:schema/>.
|
||
|
const XsdElementPtr ResolveRef(const string& element_ref) const;
|
||
|
|
||
|
// Return the XsdComplexType of the complex_type's extension base. NULL is
|
||
|
// returned if the complex_type has no extension base or if the extension
|
||
|
// base is not found within this XsdFile's target namespace.
|
||
|
XsdComplexTypePtr GetBaseType(const XsdComplexTypePtr& complex_type) const;
|
||
|
|
||
|
// Return the inheritance hierarchy of a given <xs:complexType>. The first
|
||
|
// item in the vector is this type's extension base, the next that type's
|
||
|
// extension base and so on until a type with no extension base is reached.
|
||
|
bool GetTypeHierarchy(const XsdComplexTypePtr& complex_type,
|
||
|
std::vector<XsdComplexTypePtr>* type_hier) const;
|
||
|
|
||
|
// This appends all abstract elements to the given vector.
|
||
|
void GetAbstractElements(XsdElementVector* elements) const;
|
||
|
|
||
|
// This appends all concrete complex elements to the given vector.
|
||
|
void GetComplexElements(XsdElementVector* elements) const;
|
||
|
|
||
|
// This appends all concrete simple elements to the given vector.
|
||
|
void GetSimpleElements(XsdElementVector* elements) const;
|
||
|
|
||
|
// This sorts the elements in this XSD file into 3 ranges in this order and
|
||
|
// then alphabetical order within each group: 1) abstract elements,
|
||
|
// 2) complex elements, 3) simple elements. Offset 0 is reserved/invalid.
|
||
|
void GenerateElementIdVector(XsdElementVector* elements,
|
||
|
size_t* begin_complex,
|
||
|
size_t *begin_simple) const;
|
||
|
|
||
|
// If find_type is a base type of complex_type return true, else false.
|
||
|
bool SearchTypeHierarchy(const XsdComplexTypePtr& complex_type,
|
||
|
const XsdComplexTypePtr& find_type) const;
|
||
|
|
||
|
// Return all elements derived from the given complex type.
|
||
|
void GetElementsOfType(const XsdComplexTypePtr& complex_type,
|
||
|
XsdElementVector* elements) const;
|
||
|
|
||
|
// Return all elements derived from the given complex type name.
|
||
|
void GetElementsOfTypeByName(const string& type_name,
|
||
|
XsdElementVector* elements) const;
|
||
|
|
||
|
private:
|
||
|
XsdSchemaPtr xsd_schema_;
|
||
|
XsdElementMap element_map_;
|
||
|
XsdTypeMap type_map_;
|
||
|
XsdAliasMap alias_map_;
|
||
|
};
|
||
|
|
||
|
} // end namespace kmlxsd
|
||
|
|
||
|
#endif // KML_XSD_XSD_FILE_H__
|