📄 schemaparser.java
字号:
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
package org.dom4j.datatype;
import com.sun.msv.datatype.xsd.DatatypeFactory;
import com.sun.msv.datatype.xsd.TypeIncubator;
import com.sun.msv.datatype.xsd.XSDatatype;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
import org.dom4j.util.AttributeHelper;
import org.relaxng.datatype.DatatypeException;
import org.relaxng.datatype.ValidationContext;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
/**
* <p>
* <code>SchemaParser</code> reads an XML Schema Document.
* </p>
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
* @author Yuxin Ruan
* @version $Revision: 1.19 $
*/
public class SchemaParser {
private static final Namespace XSD_NAMESPACE = Namespace.get("xsd",
"http://www.w3.org/2001/XMLSchema");
// Use QNames for the elements
private static final QName XSD_ELEMENT = QName
.get("element", XSD_NAMESPACE);
private static final QName XSD_ATTRIBUTE = QName.get("attribute",
XSD_NAMESPACE);
private static final QName XSD_SIMPLETYPE = QName.get("simpleType",
XSD_NAMESPACE);
private static final QName XSD_COMPLEXTYPE = QName.get("complexType",
XSD_NAMESPACE);
private static final QName XSD_RESTRICTION = QName.get("restriction",
XSD_NAMESPACE);
private static final QName XSD_SEQUENCE = QName.get("sequence",
XSD_NAMESPACE);
private static final QName XSD_CHOICE = QName.get("choice", XSD_NAMESPACE);
private static final QName XSD_ALL = QName.get("all", XSD_NAMESPACE);
private static final QName XSD_INCLUDE = QName
.get("include", XSD_NAMESPACE);
/** Document factory used to register Element specific factories */
private DatatypeDocumentFactory documentFactory;
/**
* Cache of <code>XSDatatype</code> instances loaded or created during
* this build
*/
private Map dataTypeCache = new HashMap();
/** NamedTypeResolver */
private NamedTypeResolver namedTypeResolver;
/** target namespace */
private Namespace targetNamespace;
public SchemaParser() {
this(DatatypeDocumentFactory.singleton);
}
public SchemaParser(DatatypeDocumentFactory documentFactory) {
this.documentFactory = documentFactory;
this.namedTypeResolver = new NamedTypeResolver(documentFactory);
}
/**
* Parses the given schema document
*
* @param schemaDocument
* is the document of the XML Schema
*/
public void build(Document schemaDocument) {
this.targetNamespace = null;
internalBuild(schemaDocument);
}
public void build(Document schemaDocument, Namespace namespace) {
this.targetNamespace = namespace;
internalBuild(schemaDocument);
}
private synchronized void internalBuild(Document schemaDocument) {
Element root = schemaDocument.getRootElement();
if (root != null) {
// handle schema includes
Iterator includeIter = root.elementIterator(XSD_INCLUDE);
while (includeIter.hasNext()) {
Element includeElement = (Element) includeIter.next();
String inclSchemaInstanceURI = includeElement
.attributeValue("schemaLocation");
EntityResolver resolver = schemaDocument.getEntityResolver();
try {
if (resolver == null) {
String msg = "No EntityResolver available";
throw new InvalidSchemaException(msg);
}
InputSource inputSource = resolver.resolveEntity(null,
inclSchemaInstanceURI);
if (inputSource == null) {
String msg = "Could not resolve the schema URI: "
+ inclSchemaInstanceURI;
throw new InvalidSchemaException(msg);
}
SAXReader reader = new SAXReader();
Document inclSchemaDocument = reader.read(inputSource);
build(inclSchemaDocument);
} catch (Exception e) {
System.out.println("Failed to load schema: "
+ inclSchemaInstanceURI);
System.out.println("Caught: " + e);
e.printStackTrace();
throw new InvalidSchemaException("Failed to load schema: "
+ inclSchemaInstanceURI);
}
}
// handle elements
Iterator iter = root.elementIterator(XSD_ELEMENT);
while (iter.hasNext()) {
onDatatypeElement((Element) iter.next(), documentFactory);
}
// handle named simple types
iter = root.elementIterator(XSD_SIMPLETYPE);
while (iter.hasNext()) {
onNamedSchemaSimpleType((Element) iter.next());
}
// hanlde named complex types
iter = root.elementIterator(XSD_COMPLEXTYPE);
while (iter.hasNext()) {
onNamedSchemaComplexType((Element) iter.next());
}
namedTypeResolver.resolveNamedTypes();
}
}
// Implementation methods
// -------------------------------------------------------------------------
/**
* processes an XML Schema <element> tag
*
* @param xsdElement
* DOCUMENT ME!
* @param parentFactory
* DOCUMENT ME!
*/
private void onDatatypeElement(Element xsdElement,
DocumentFactory parentFactory) {
String name = xsdElement.attributeValue("name");
String type = xsdElement.attributeValue("type");
QName qname = getQName(name);
DatatypeElementFactory factory = getDatatypeElementFactory(qname);
if (type != null) {
// register type with this element name
XSDatatype dataType = getTypeByName(type);
if (dataType != null) {
factory.setChildElementXSDatatype(qname, dataType);
} else {
QName typeQName = getQName(type);
namedTypeResolver.registerTypedElement(xsdElement, typeQName,
parentFactory);
}
return;
}
// handle element types derrived from simpleTypes
Element xsdSimpleType = xsdElement.element(XSD_SIMPLETYPE);
if (xsdSimpleType != null) {
XSDatatype dataType = loadXSDatatypeFromSimpleType(xsdSimpleType);
if (dataType != null) {
factory.setChildElementXSDatatype(qname, dataType);
}
}
Element schemaComplexType = xsdElement.element(XSD_COMPLEXTYPE);
if (schemaComplexType != null) {
onSchemaComplexType(schemaComplexType, factory);
}
Iterator iter = xsdElement.elementIterator(XSD_ATTRIBUTE);
if (iter.hasNext()) {
do {
onDatatypeAttribute(xsdElement, factory, (Element) iter
.next());
} while (iter.hasNext());
}
}
/**
* processes an named XML Schema <complexTypegt; tag
*
* @param schemaComplexType
* DOCUMENT ME!
*/
private void onNamedSchemaComplexType(Element schemaComplexType) {
Attribute nameAttr = schemaComplexType.attribute("name");
if (nameAttr == null) {
return;
}
String name = nameAttr.getText();
QName qname = getQName(name);
DatatypeElementFactory factory = getDatatypeElementFactory(qname);
onSchemaComplexType(schemaComplexType, factory);
namedTypeResolver.registerComplexType(qname, factory);
}
/**
* processes an XML Schema <complexTypegt; tag
*
* @param schemaComplexType
* DOCUMENT ME!
* @param elementFactory
* DOCUMENT ME!
*/
private void onSchemaComplexType(Element schemaComplexType,
DatatypeElementFactory elementFactory) {
Iterator iter = schemaComplexType.elementIterator(XSD_ATTRIBUTE);
while (iter.hasNext()) {
Element xsdAttribute = (Element) iter.next();
String name = xsdAttribute.attributeValue("name");
QName qname = getQName(name);
XSDatatype dataType = dataTypeForXsdAttribute(xsdAttribute);
if (dataType != null) {
// register the XSDatatype for the given Attribute
// #### should both these be done?
// elementFactory.setChildElementXSDatatype( qname, dataType );
elementFactory.setAttributeXSDatatype(qname, dataType);
}
}
// handle sequence definition
Element schemaSequence = schemaComplexType.element(XSD_SEQUENCE);
if (schemaSequence != null) {
onChildElements(schemaSequence, elementFactory);
}
// handle choice definition
Element schemaChoice = schemaComplexType.element(XSD_CHOICE);
if (schemaChoice != null) {
onChildElements(schemaChoice, elementFactory);
}
// handle all definition
Element schemaAll = schemaComplexType.element(XSD_ALL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -