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

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


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.
At each SchemaProperty I am looking for an annotation with: schemaProperty.getType().getAnnotation(), but I don't find any annotation. (java code below)



I examine for example the following xsd-file:



Figure of xsd structure:



figure of xsd structure



Xsd source code:


<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);



Here is the java code:


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?





A solution was already shown here: stackoverflow.com/questions/42965146/…
– Gio
Jan 28 at 12:40





But this solution above does not read annotations declared directly as children of elements but only annotations that are declared as children of type definitions. So in the example above "<xs:documentation>annotation for ExterneDaten</xs:documentation>" will not be read but the following will be read: <xs:documentation>annotation for Type ExterneDaten</xs:documentation>
– Gio
Jan 28 at 12:54




1 Answer
1



I had the same requirement and was able to parse the Annotations in XSD as shown below.



Say the XSD is as follows:-


<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 clreated above as follows :-


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



Now we add the custom annotaion parser to XSOMParser which we use for parsing XSD as follows:-


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 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 :-


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

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

XSAttributeUse next = attributes.next();
XSAttributeDecl attributeDecl = next.getDecl();
//vivek
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();
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

Blogger: Contempo template have managed to get the posts to post in full but there is still a “snippet” of the post at the bottom of each full post