⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 schemaparser.java

📁 解决如何把XML应用到JAVA里问题
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 &lt;element&gt; 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 &lt;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 &lt;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 + -