In Java, how do I parse an xml schema (xsd) to learn what's valid at a given element?

前端 未结 6 1967
感动是毒
感动是毒 2021-02-08 23:01

I\'d like to be able to read in an XML schema (i.e. xsd) and from that know what are valid attributes, child elements, values as I walk through it.

For example, let\'s

6条回答
  •  旧巷少年郎
    2021-02-08 23:14

    This is a good question. Although, it is old, I did not find an acceptable answer. The thing is that the existing libraries I am aware of (XSOM, Apache XmlSchema) are designed as object models. The implementors did not have the intention to provide any utility methods — you should consider implement them yourself using the provided object model.

    Let's see how querying context-specific elements can be done by the means of Apache XmlSchema.

    You can use their tutorial as a starting point. In addition, Apache CFX framework provides the XmlSchemaUtils class with lots of handy code examples.

    First of all, read the XmlSchemaCollection as illustrated by the library's tutorial:

    XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
    xmlSchemaCollection.read(inputSource, new ValidationEventHandler());
    

    Now, XML Schema defines two kinds of data types:

    • Simple types
    • Complex types

    Simple types are represented by the XmlSchemaSimpleType class. Handling them is easy. Read the documentation: https://ws.apache.org/commons/XmlSchema/apidocs/org/apache/ws/commons/schema/XmlSchemaSimpleType.html. But let's see how to handle complex types. Let's start with a simple method:

    @Override
    public List getChildElementNames(QName parentElementName) {
        XmlSchemaElement element = xmlSchemaCollection.getElementByQName(parentElementName);
        XmlSchemaType type = element != null ? element.getSchemaType() : null;
    
        List result = new LinkedList<>();
        if (type instanceof XmlSchemaComplexType) {
            addElementNames(result, (XmlSchemaComplexType) type);
        }
        return result;
    }
    

    XmlSchemaComplexType may stand for both real type and for the extension element. Please see the public static QName getBaseType(XmlSchemaComplexType type) method of the XmlSchemaUtils class.

    private void addElementNames(List result, XmlSchemaComplexType type) {
        XmlSchemaComplexType baseType = getBaseType(type);
        XmlSchemaParticle particle = baseType != null ? baseType.getParticle() : type.getParticle();
    
        addElementNames(result, particle);
    }
    

    When you handle XmlSchemaParticle, consider that it can have multiple implementations. See: https://ws.apache.org/commons/XmlSchema/apidocs/org/apache/ws/commons/schema/XmlSchemaParticle.html

    private void addElementNames(List result, XmlSchemaParticle particle) {
        if (particle instanceof XmlSchemaAny) {
    
        } else if (particle instanceof XmlSchemaElement) {
    
        } else if (particle instanceof XmlSchemaGroupBase) {
    
        } else if (particle instanceof XmlSchemaGroupRef) {
    
        }
    }
    

    The other thing to bear in mind is that elements can be either abstract or concrete. Again, the JavaDocs are the best guidance.

提交回复
热议问题