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.30</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);
}
}
<?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
- Details - Fixes clones not cloning attributes and elements of XsdMultipleElements.
- Details - Removes assignment of the XsdElement as parent of the XsdComplexType when the type attribute was being resolved for the XsdElement. This was the cause of some circular reference issues.
- Adds XsdAbstractElement.getXsdSchema() which returns the XsdSchema of any given XsdAbstractElement based on the parent of the XsdAbstractElement. Suggested by: hein4daddel
- Details - Changes xsd:minInclusive, xsd:maxInclusive, xsd:minExclusive and xsd:maxExclusive to have a String value instead of a Double value.
- Changes XsdParserCore.addFileToParse to not allow files with paths that start with http, as this isn't supported.
- Details - Adds a new XsdAbstractElement to represent XsdBuiltInDataTypes;
- Details - Changes the way Visitors work in order to detach elements from visitors. Now the elements and visitors are associated by configuration.
- Details - Fixes a bug where a verification was missing while using getComplexType.
- Changes some of the static fields of XsdAbstractElement to allow avoiding using hardcoded strings while getting attributes.
- Details - Changes the parse for Xsd:AppInfo and Xsd:Documentation - Now the parser returns the exact contents of these two elements.
- 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.