public class XsdAnnotation extends XsdAbstractElement {
private String id;
private List<XsdAppInfo> appInfoList = new ArrayList<>();
private List<XsdDocumentation> documentations = new ArrayList<>();
// (...)
}
<dependency>
<groupId>com.github.xmlet</groupId>
<artifactId>xsdParser</artifactId>
<version>1.0.23</version>
</dependency>
public class ParserApp {
public static void main(String [] args) {
String filePath = "Your file path here.";
XsdParser parserInstance1 = new XsdParser(filePath);
//or
String jarPath = "Your jar path here.";
String jarXsdPath = "XSD file path, relative to the jar root.";
XsdParserJar parserInstance2 = new XsdParserJar(jarPath, jarXsdPath);
Stream<XsdElement> elementsStream = parserInstance1.getResultXsdElements(filePath);
Stream<XsdSchema> schemasStream = parserInstance1.getResultXsdSchemas(filePath);
}
}
![](https://raw.githubusercontent.com/xmlet/XsdParser/master/src/main/java/org/xmlet/xsdparser/xsdelements/xsdelements.png)
<?xml version='1.0' encoding='utf-8' ?>
<xsd:schema xmlns='http://schemas.microsoft.com/intellisense/html-5' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:group name="flowContent">
<xsd:all>
<xsd:element name="elem1"/>
</xsd:all>
</xsd:group>
<xs:element name="html">
<xs:complexType>
<xsd:choice>
<xsd:group ref="flowContent"/>
</xsd:choice>
<xs:attribute name="manifest" type="xsd:anyURI" />
</xs:complexType>
</xs:element>
</xsd:schema>
public class ParserApp {
public static void main(String [] args) {
//(...)
XsdElement htmlElement = elementsStream.findFirst().get();
XsdComplexType htmlComplexType = htmlElement.getXsdComplexType();
XsdAttribute manifestAttribute = htmlComplexType.getXsdAttributes().findFirst().get();
XsdChoice choiceElement = htmlComplexType.getChildAsChoice();
XsdGroup flowContentGroup = choiceElement.getChildrenGroups().findFirst().get();
XsdAll flowContentAll = flowContentGroup.getChildAsAll();
XsdElement elem1 = flowContentAll.getChildrenElements().findFirst().get();
}
}
Our parse process is also based on a tree approach, which means that when we invoke the XsdSchema parse function the whole document will be parsed, because each XsdAbstractElement class extracts its respective information, i.e. a XsdSchema instance extracts information from the received xsd:schema Node object, and also invokes the respective parse function for each children elements present in its current Node object.
class XsdComplexContentVisitor extends XsdAnnotatedElementsVisitor {
private final XsdComplexContent owner;
@Override
public void visit(XsdRestriction element) {
owner.setRestriction(ReferenceBase.createFromXsd(element));
}
@Override
public void visit(XsdExtension element) {
owner.setExtension(ReferenceBase.createFromXsd(element));
}
}
- DEFAULT ("")
- EXTENSION ("extension")
- RESTRICTION ("restriction")
- LIST("list")
- UNION("union")
- ALL ("#all")
There are other validations, such as veryfing if a given attribute is a positiveInteger, a nonNegativeInteger, etc. If any of these validations fail an exception will be thrown with a message detailing the failed validation.
"A xsd:element cannot have a ref attribute if its parent is a xsd:schema element."
This means that after creating the XsdElement instance and populating its fields we invoke a method to verify this rule. If the rule is violated then an exception is thrown with a message detailing the issue.
UnsolvedElement - Wrapper class to each element that has a ref attribute.
ConcreteElement - Wrapper class to each element that is present in the file.
NamedConcreteElement - Wrapper class to each element that is present in the file and has a name attribute present.
ReferenceBase - A common interface between UnsolvedReference and ConcreteElement.
These classes simplify the reference solving process by serving as a classifier to the element that they wrap. Now we will shown a short example to explain how this works:
<?xml version='1.0' encoding='utf-8' ?>
<xsd:schema xmlns='http://schemas.microsoft.com/intellisense/html-5' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:group id="replacement" name="flowContent"> <!-- NamedConcreteType wrapping a XsdGroup -->
(...)
</xsd:group>
<xsd:choice> <!-- ConcreteElement wrapping a XsdChoice -->
<xsd:group id="toBeReplaced" ref="flowContent"/> <!-- UnsolvedReference wrapping a XsdGroup -->
</xsd:choice>
</xsd:schema>
Resuming the approach:
- Obtain all the NamedConcreteElements objects.
- Obtain all the UnsolvedReference objects. Iterate them to perform a lookup search in the previously obtained NamedConcreteElements objects by comparing the UnsolvedReference ref with the NamedConcreteElements name attributes.
- If a match is found, replace the UnsolvedReference wrapped object with the NamedConcreteElements wrapped object.
Sonarcloud Statistics
- Issue 12 - Exception handling during parsing - Adds proper exception propagation when an exception occurs.
- Issue 11 - Schema Import: Search in relation to the path of the importing XSD file - Changes XsdParser to support imports with paths relative to the importing file.
- Issue 10 - documentation.getContent() - Fixes CDATA nodes not being parsed XSD elements with raw text such as "xsd:documentation" and "xsd:appinfo".
- Issue 9 - Issue with substitutionGroup - Fixed substitutionGroup automatically overwriting XsdElement types. To access the substitution element types use XsdElement::getXsdSubstitutionGroup() and then access the types.
- Addresses multiple namespace usage while parsing. Also reworks how "xsd:includes" and "xsd:import" work. Full explanation here
- Issue 7 - XsdParser::getSchemaNode fails with comments - Added verification to only parse Element nodes.
- Issue 8 - Resolve tags without "xs" and "xsd" namespaces. - Adds support for configurable namespaces of XSD elements.
- Replaces XsdExtension using XsdElement as value for its base attribute with XsdComplexType and XsdSimpleType types.
- Fixes XsdElement substitutionGroup not being used to replace elements contents.
- Adds support for parsing XSD files inside Jar files.
- Project-wide documentation.
- Minor bug fixes.
- Adds XSD complex rule validations.
- Adds exceptions with detailed messages, providing more information to the user.
- Adds attribute type validations and validations of possible values with Enum classes.