简体   繁体   English

如何使用Apache XMLBeans从Xsd-Schema中读取Xsd-Annotations?

[英]How to read Xsd-Annotations from Xsd-Schema using Apache XMLBeans?

I read a xsd-schema file using Apache XMLBeans , iterating over all SchemaProperties beginning with the root element. 我使用Apache XMLBeans读取了一个xsd-schema文件 ,并从根元素开始遍历所有SchemaProperty At each SchemaProperty I am looking for an annotation with: schemaProperty.getType().getAnnotation() , but I don't find any annotation. 在每个SchemaProperty上,我都在寻找带有以下内容的注释: schemaProperty.getType()。getAnnotation() ,但没有找到任何注释。 (java code below) (下面的Java代码)

I examine for example the following xsd-file: 例如,我检查以下xsd文件:

Figure of xsd structure: xsd结构图:

xsd结构图

Xsd source code: Xsd源代码:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="ExterneDaten" type="ExterneDaten">
    <xs:annotation>
        <xs:documentation>annotation for ExterneDaten</xs:documentation>
    </xs:annotation>
</xs:element>
<xs:complexType name="ExterneDaten">
    <xs:annotation>
        <xs:documentation>annotation for Type ExterneDaten</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="value1" type="xs:string">
            <xs:annotation>
                <xs:documentation>annotation for value1</xs:documentation>
            </xs:annotation>
        </xs:element>
    </xs:sequence>
    <xs:attribute name="isTest" type="xs:boolean">
        <xs:annotation>
            <xs:documentation>annotation for boolean attribute isTest</xs:documentation>
        </xs:annotation>
    </xs:attribute>
</xs:complexType>

I examine the xsd with my function: MyXsdReader.readAllAnnotationsFromXsd(String schema) ; 我用我的函数检查xsd: MyXsdReader.readAllAnnotationsFromXsd(String schema) ;

Here is the java code: 这是Java代码:

public class MyXsdReader
{

    public static void readAllAnnotationsFromXsd(String newSchema)
    {
        try
        {
            SchemaTypeLoader loader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader());

            XmlObject[] xmlObjects = new XmlObject[1];
            XmlOptions options = new XmlOptions();
            options.setLoadLineNumbers().setLoadMessageDigest().setCharacterEncoding("utf-8");
            options.setCompileDownloadUrls();
            xmlObjects[0] = loader.parse(newSchema, null, options);
            SchemaTypeSystem sts = XmlBeans.compileXsd(xmlObjects, XmlBeans.getBuiltinTypeSystem(), options);
            readXsdRootElement(sts);

        }
        catch (Exception e)
        {
            System.out.println("makeXsdListRootEle(): Excpetion: " + e.getMessage());
        }
    }

    private static void readXsdRootElement(SchemaTypeSystem sts)
    {
        SchemaGlobalElement[] globals = sts.globalElements();
        if (globals != null && globals.length == 1)
        {
            SchemaGlobalElement sge = globals[0];
            SchemaType st = sge.getType();
            SchemaProperty[] properties = st.getProperties();
            for (int k = 0; k < properties.length; k++)
            {
            SchemaProperty property = properties[k];
            checkAnnotation(property);
            if (property.isAttribute() == false)
            {
                readXsdProperty(property);
            }
            }
        }
    }

    private static void readXsdProperty(SchemaProperty property)
    {
        SchemaProperty[] properties = property.getType().getProperties();
        for (SchemaProperty schemaProperty : properties)
        {
            checkAnnotation(schemaProperty);
            readXsdProperty(schemaProperty);
        }
    }

    private static void checkAnnotation(SchemaProperty schemaProperty)
    {
        SchemaAnnotation annotation = schemaProperty.getType().getAnnotation();
        if (annotation != null)
        {
            System.out.println(annotation.toString());
        }
    }
}

What do I have to do, to be able to read the annotations inside the xsd? 为了能够读取xsd内的注释,我该怎么办?

I had the same requirement and was able to parse the Annotations in XSD as shown below. 我有相同的要求,并且能够解析XSD中的Annotations,如下所示。

Say the XSD is as follows:- 说XSD如下:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="ExterneDaten" type="ExterneDaten">
    <xs:annotation>
        <xs:documentation>annotation for ExterneDaten</xs:documentation>
    </xs:annotation>
</xs:element>
<xs:complexType name="ExterneDaten">
    <xs:annotation>
        <xs:documentation>annotation for Type ExterneDaten</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="value1" type="xs:string">
            <xs:annotation>
                <xs:documentation>annotation for value1</xs:documentation>
            </xs:annotation>
        </xs:element>
    </xs:sequence>
    <xs:attribute name="isTest" type="xs:boolean">
        <xs:annotation>
            <xs:documentation>annotation for boolean attribute isTest</xs:documentation>
        </xs:annotation>
    </xs:attribute>
</xs:complexType>

Now, we have to create a custom Annotation Parser as follows:- 现在,我们必须创建一个自定义注释解析器,如下所示:

public class XSDAnnotaionParser extends AnnotationParser {

    private StringBuilder documentation = new StringBuilder();

    @Override
    public ContentHandler getContentHandler(AnnotationContext context, String parentElementName, ErrorHandler handler,
            EntityResolver resolver) {
        return new ContentHandler() {
            private boolean parsingDocumentation = false;

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                if (parsingDocumentation) {
                    documentation.append(ch, start, length);
                }
            }

            @Override
            public void endElement(String uri, String localName, String name) throws SAXException {
                //say you want to parse the text in "documentaion" tag in your xsd....this is where we scpecify the tag
                if (localName.equals("documentation")) {
                    parsingDocumentation = false;
                }
            }

            @Override
            public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
                if (localName.equals("documentation")) {
                    parsingDocumentation = true;
                }
            }

            @Override
            public void setDocumentLocator(Locator locator) {
                // TODO Auto-generated method stub

            }

            @Override
            public void startDocument() throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void endDocument() throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void startPrefixMapping(String prefix, String uri) throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void endPrefixMapping(String prefix) throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void processingInstruction(String target, String data) throws SAXException {
                // TODO Auto-generated method stub

            }

            @Override
            public void skippedEntity(String name) throws SAXException {
                // TODO Auto-generated method stub

            }
        };
    }

    @Override
    public Object getResult(Object existing) {
        return documentation.toString().trim();
    }
}

Now we create a factory class for the custom annotation parser which we created above as follows:- 现在,我们为上面创建的自定义注释解析器创建一个工厂类,如下所示:

class AnnotationFactory implements AnnotationParserFactory {
    @Override
    public AnnotationParser create() {
        return new XSDAnnotaionParser();
    }
}

Now we add the custom annotation parser to XSOMParser which we use for parsing XSD as follows:- 现在,我们将自定义注释解析器添加到XSOMParser中,用于解析XSD,如下所示:

XSOMParser parser = new XSOMParser();
parser.setAnnotationParser(new AnnotationFactory());
try {
    parser.parse(xml);
} catch (SAXException ex) {
    throw new SchemaException(ex);
}

For parsing the documentation tag we can use the code as below:- 为了解析文档标签,我们可以使用如下代码:

XSSchemaSet schemaSet = null;
        try {
            schemaSet = parser.getResult();
        } catch (SAXException ex) {
            throw new SchemaException(ex);
        }

        Iterator<XSElementDecl> iterator = schemaSet.iterateElementDecls();
    while (iterator.hasNext()) {
        XSElementDecl elementDecl= (XSElementDecl) iterator.next();
        XSComplexType eleCompDecl= elementDecl.getType().asComplexType();
        if (eleCompDecl!= null) {
            //we get the annotation here
            XSAnnotation annotaion = eleCompDecl.getAnnotation();
            //this will print the tezxt inside documentaion tag
            System.out.println(annotaion.getAnnotation());
        }
    }

Code for reading annotaions inside attributes of an xsd is as follows :- 用于读取xsd属性内部注释的代码如下:-

            Collection<? extends XSAttributeUse> attributes= eleCompDecl.getAttributeUses();

            Iterator<? extends XSAttributeUse> iterator = attributes.iterator();
            while(attributes.hasNext()) {

                XSAttributeUse next = attributes.next();
                XSAttributeDecl attributeDecl = next.getDecl(); 
                String desc = null;
                if(attributeDecl != null) {
                    try {
                        desc = (String)attributeDecl.getAnnotation().getAnnotation();
                        System.out.println("the documentaion for the attribute is "+desc)
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

I ran into the same problem and solved it for me with Apache xmlbeans in the way described below. 我遇到了同样的问题,并使用Apache xmlbeans为我解决了以下问题。 The example is basically Groovy code but should be easy transferable to Java. 该示例基本上是Groovy代码,但应易于转移到Java。

void parseDocumentations(File xsdFile) {
    // load the xsd
    XmlObject object = XmlObject.Factory.parse(xsdFile)
    List<XmlObject> objectList = []
    objectList.add(object)
    // parse the xsd content to a object tree
    SchemaTypeSystem sts = XmlBeans.compileXsd((XmlObject[])objectList.toArray(), XmlBeans.getBuiltinTypeSystem(), null)
    def globalTypes = sts.globalTypes()
    // iterate over the defined types in the xsd
    for (SchemaType type: globalTypes) {
        def annotation = type.getAnnotation()
        if (annotation!=null) {
            // get the sub xml nodes of the annotation node
            def userInfos = annotation.userInformation
            for (XmlObject userInfo: userInfos ) {
                if (userInfo.getDomNode().localName=='documentation') {
                    // extract the text from documentation node
                    def documentationTxt = userInfo.getDomNode().getFirstChild().getNodeValue()
                    println documentationTxt
                }
            }
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM