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.2.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();
Stream<XsdSchema> schemasStream = parserInstance1.getResultXsdSchemas();
}
}
<?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
Adds xs:anyAttribute, xs:notation, xs:unique, xs:key, xs:keyref, xs:selector, and xs:field, bringing element coverage to 42/42. Each element enforces its spec attribute set (NCName/QName/token lexical checks, unknown-attribute rejection), child cardinality and ordering, parent-type restrictions, and the relevant schema-level constraints — name uniqueness within target namespace, xs:keyref scope and field-count rules, and xs:anyAttribute wildcard subset/union along derivation chains.
- Parent scoping —
xs:include,xs:redefinemust be underxs:schema;xs:choice/xs:sequencerestricted to model-group parents;xs:complexTypeabstract/final/blockonly at top-level. - Mutex / presence rules —
refvs inline attributes/children onxs:element,xs:attribute,xs:attributeGroup,xs:group,xs:list,xs:union;fixedvsdefaultanduseinteractions onxs:attribute/xs:element;xs:simpleTyperequires exactly one ofrestriction/list/union;xs:simpleContent/xs:complexContentrequire exactly one ofrestriction/extension;baserequired onxs:extensionand onxs:restrictionnested in content-model wrappers. - Value / range checks —
minOccurs≤maxOccursacrossxs:element/xs:choice/xs:sequence/xs:group/xs:any;xs:allchildmaxOccurs∈ {0,1}; numeric facet ordering (minLength≤maxLength,fractionDigits≤totalDigits,min/maxInclusive,min/maxExclusive); facetvalueattribute required. - Token / enum validation —
xs:anyprocessContents∈ {strict,lax,skip} andnamespacetoken list;xs:schemablockDefault/finalDefaultenum token lists;xs:importnamespacemust be a URI and differ from the enclosingtargetNamespace;xs:appinfo/xs:documentationsourcemust be a URI. - Reference target kinds —
xs:listitemType,xs:unionmemberTypes, andxs:restrictionbaserejectxs:complexTypetargets where the spec requires a simple type;xs:extensionbasechecked againstsimpleContent/complexContentparent.
- Spec-conformant override mechanism scoped by transitive include/import visibility. Direct base-importers still see originals; chained and circular-
basecases resolved deterministically. Newredefine_external_{a,b,c,d}.xsdfixtures andRedefineTestcoverage.
- Redefined types/groups/attribute groups no longer resolve to their originals in chained include/redefine scenarios.
- Details - Improves the Parser to support xsd:redefine. Contribution by David Al-Kanani.
- Details - Improves the Parser to keep solving unsolved references until a run no longer resolves any unsolved reference. Fix by HennoVermeulen.
- Details - Small change to keep minOccurs/maxOccurs when the unsolved element is resolved. Fix by HennoVermeulen.
- Details - Adds xsd:any type to the Parser.
- Details - Fixes getResultXsdSchemas return order. Fix by SimonCockx.
- Details - Fixes default value mapping on XsdAttributes. Fixes by Carsten Zerbst.
- Details - Improves unsolved references resolution. Fixes by SimonCockx.
- Details - Fixes infinite type lookups on circular includes. Fixes by jonherrmann.
- Details - Fixes comparison to match included file paths to parsed files paths.
- Details - Introduces changes to allow any kind of prefix at runtime for the purposes of determining built-in types and parse functions.
- Details - Parsing an XSD with no or a different prefix than xs or xsd fails with a ParsingException.
- Details - Fixes getXsdSimpleType on XsdAttributes when simpleTypes are XsdBuiltIntTypes. Includes suggestions by Matteo Franci.
- Details - Fixes some instances where unsolved references were being added twice, resulting in unattached pointers in the final Unsolved References list. Includes suggestions by Daniel Radtke.
- Details - Adds resolving Unsolved Elements on XsdUnion member types. Fixes by Daniel Radtke.
- Details - Adds support for transitive includes. Fixes by Simon Cockx.
- Details - Applies a quick fix when the Parser returns still with UnsolvedReferences, even when all the references are solved. With the help of Daniel Radtke.
- Details - Reverts XsdRestriction getPattern to keep the previous behaviour. Added a new method getPatterns with the new behaviour.
- Details - Changes XsdMultipleElements to maintain order of elements inside Choice/Sequence/All. Fixes by Simon Cockx.
- Details - Changes XsdRestriction to support multiple patterns instead of one. Fixes by Daniel Radtke.
- Details - Adds fallback when searching for XsdSchema while solving Unsolved References. Fixes by Carsten Zerbst.
- Details - Changes XsdRestriction to support XsdComplexTypes related with the base attribute.
- Details Possible Breaking Change - Changed DocumentBuilderFactory to be NameSpaceAware. Namespaces will now be validated.
- Details File path bug fixes by Wael-Fathallah.
- Details Adds support for XsdAll, XsdChoice, XsdGroup and XsdSequence inside a XsdRestriction.
-
Fixed cloning. Reference resolving now properly clones the referred element and all its children, also cloning
the possible unsolved references of the clone. This has two effects:
- The reference solving process is now more accurate - The referred element unsolved references are also resolved. Previously if an element resolved 10 references the 10 references would have unsolved references and the base element which was the source of the cloned objects would have the references solved.
- To avoid eating up memory I had to implement a temporary solution which will cause the getParent call to return null in certain elements which were children of cloned elements.
- Details This should be finally solved due to the more accurate reference solving process.
- Details Solved due to the more accurate reference solving process.
- Details Minor correction to fix the problem.
- Details Adds safeguard to usage of prefixes of a namespace inside itself.
- Fixes some XML Injection vulnerabilities.
- Code cleanup and adjustments for SonarCloud validation.
- Details - Adds support for xsd:includes elements with schema locations with http or https locations. Previously it only supported local XSD files. Fixes the usage of xsd:import to properly resolve namespace references.
- 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.
- Details - Adds proper exception propagation when an exception occurs.
- Details - Changes XsdParser to support imports with paths relative to the importing file.
- Details - Fixes CDATA nodes not being parsed XSD elements with raw text such as "xsd:documentation" and "xsd:appinfo".
- Details - 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
- 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.