1010import org .xml .sax .InputSource ;
1111import org .xml .sax .SAXException ;
1212
13+ import javax .xml .namespace .NamespaceContext ;
1314import javax .xml .parsers .DocumentBuilder ;
1415import javax .xml .parsers .DocumentBuilderFactory ;
1516import javax .xml .parsers .ParserConfigurationException ;
17+ import javax .xml .xpath .XPath ;
18+ import javax .xml .xpath .XPathConstants ;
19+ import javax .xml .xpath .XPathExpressionException ;
20+ import javax .xml .xpath .XPathFactory ;
1621
17- import java .io .InputStream ;
1822import java .io .IOException ;
19- import java .io .StringReader ;
20- import java .nio .charset .StandardCharsets ;
23+ import java .io .InputStream ;
2124import java .util .ArrayList ;
25+ import java .util .Iterator ;
2226import java .util .List ;
2327
24- import static org .junit .jupiter .api .Assertions .assertTrue ;
2528import static org .junit .jupiter .api .DynamicTest .dynamicTest ;
2629
2730public class XmlCatalogVerificationTest {
2831
2932 /**
30- * Tests the XML catalog by parsing the xmlcatalog.xml file and checking if the namespaces
31- * in the XSD schema files match the namespaces defined in the xmlcatalog.xml file.
33+ * Tests the XML catalog by parsing the xmlcatalog.xml file and verifying if the XML namespaces
34+ * in the referenced XSD schema files match the XML namespaces defined in the xmlcatalog.xml file.
3235 *
3336 * @return a list of dynamic tests for each URI in the xmlcatalog.xml file
3437 * @throws IOException if an I/O error occurs while reading the XML catalog file
3538 * @throws ParserConfigurationException if a parser configuration error occurs
3639 * @throws SAXException if a SAX error occurs while parsing the XML catalog file
40+ * @throws XPathExpressionException if an XPath expression error occurs
3741 */
3842 @ TestFactory
39- public List <DynamicTest > testXmlCatalog () throws IOException , ParserConfigurationException , SAXException {
40- // Define the path to the XML catalog file
43+ public List <DynamicTest > testXmlCatalog () throws IOException , ParserConfigurationException , SAXException , XPathExpressionException {
44+ // Define the path to the XML catalog file. This is relative to "${basedir}/../schema" in the pom.xml.
4145 String xmlCatalogFilename = "xmlcatalog.xml" ;
4246
4347 // Load the XML catalog file from the classpath
4448 ClassLoader classLoader = getClass ().getClassLoader ();
4549 InputStream xmlCatalogStream = classLoader .getResourceAsStream (xmlCatalogFilename );
4650
51+ // Ensure the XML catalog file is found
4752 Assertions .assertNotNull (xmlCatalogStream , "XML catalog file not found" );
4853
4954 // Parse the xmlcatalog.xml file
5055 DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance ();
56+ factory .setNamespaceAware (true ); // Make the factory namespace-aware
5157 DocumentBuilder builder = factory .newDocumentBuilder ();
5258 Document xmlCatalogDocument = builder .parse (new InputSource (xmlCatalogStream ));
5359
@@ -60,39 +66,64 @@ public List<DynamicTest> testXmlCatalog() throws IOException, ParserConfiguratio
6066 // Iterate through the XML catalog elements
6167 for (int i = 0 ; i < xmlCatalogElements .getLength (); i ++) {
6268 Node xmlCatalogElement = xmlCatalogElements .item (i );
69+
70+ // Check if the element is a <uri> element
6371 if (xmlCatalogElement .getNodeName ().equals ("uri" )) {
64- String uriName = xmlCatalogElement .getAttributes ().getNamedItem ("name" ).getTextContent ();
72+ // Get the URI name and the local filename of the XSD schema
73+ String uriNameXmlCtlg = xmlCatalogElement .getAttributes ().getNamedItem ("name" ).getTextContent ();
6574 String xsdLocalFilename = xmlCatalogElement .getAttributes ().getNamedItem ("uri" ).getTextContent ();
6675
67- // Create a dynamic test for each URI
68- dynamicTests .add (dynamicTest ("Testing URI: " + uriName , () -> {
69- // Load the XSD schema file from the classpath
70- InputStream xsdSchemaFileStream = classLoader .getResourceAsStream (xsdLocalFilename );
71- Assertions .assertNotNull (xsdSchemaFileStream , "The following file is missing: " + xsdLocalFilename );
72-
73- // Read the XSD local file content
74- String xsdContent = new String (xsdSchemaFileStream .readAllBytes (), StandardCharsets .UTF_8 );
75-
76- // Parse the XSD file content to a Document object
77- Document xsdDocument = builder .parse (new InputSource (new StringReader (xsdContent )));
78-
79- // Check if the XSD document contains the expected namespace
80- NodeList schemaNodes = xsdDocument .getElementsByTagNameNS ("*" , "schema" );
81- boolean namespaceFound = false ;
82- for (int j = 0 ; j < schemaNodes .getLength (); j ++) {
83- Node schemaNode = schemaNodes .item (j );
84- String targetNamespace = schemaNode .getAttributes ().getNamedItem ("targetNamespace" ).getTextContent ();
85- System .out .println ("uriName.equals(targetNamespace)" + uriName .equals (targetNamespace ));
86- if (uriName .equals (targetNamespace )) {
87- namespaceFound = true ;
88- break ;
76+ // Load the XSD schema local file from the classpath
77+ InputStream xsdSchemaFileStream = classLoader .getResourceAsStream (xsdLocalFilename );
78+ Assertions .assertNotNull (xsdSchemaFileStream , "The following file is missing: " + xsdLocalFilename );
79+
80+ // Parse the XSD schema local file
81+ DocumentBuilderFactory factoryXsd = DocumentBuilderFactory .newInstance ();
82+ factoryXsd .setNamespaceAware (true ); // Make the factory namespace-aware
83+ DocumentBuilder builderXsd = factoryXsd .newDocumentBuilder ();
84+ Document xsdDocument = builderXsd .parse (new InputSource (xsdSchemaFileStream ));
85+
86+ // Create an XPath instance to evaluate the targetNamespace field found in the XSD schema
87+ XPath xPath = XPathFactory .newInstance ().newXPath ();
88+ xPath .setNamespaceContext (new NamespaceContext () {
89+ @ Override
90+ public String getNamespaceURI (String prefix ) {
91+ // Define the namespace URI for the xs prefix
92+ if ("xs" .equals (prefix )) {
93+ return "http://www.w3.org/2001/XMLSchema" ;
94+ }
95+ return null ;
96+ }
97+
98+ @ Override
99+ public String getPrefix (String namespaceURI ) {
100+ // Define the prefix for the namespace URI
101+ if ("http://www.w3.org/2001/XMLSchema" .equals (namespaceURI )) {
102+ return "xs" ;
89103 }
104+ return null ;
90105 }
91- assertTrue (namespaceFound , "The namespace " + uriName + " is not present in file " + xsdLocalFilename );
106+
107+ @ Override
108+ public Iterator <String > getPrefixes (String namespaceURI ) {
109+ return null ;
110+ }
111+ });
112+
113+ // Evaluate the targetNamespace attribute from the XSD document
114+ String targetNamespace = (String ) xPath .evaluate ("/xs:schema/@targetNamespace" , xsdDocument , XPathConstants .STRING );
115+
116+ // Assert if the targetNamespace from the XSD file matches the uriNameXmlCtlg from the XML catalog
117+ Assertions .assertEquals (uriNameXmlCtlg , targetNamespace , "The namespace " + uriNameXmlCtlg + " does not match the targetNamespace in file " + xsdLocalFilename );
118+
119+ // Create a dynamic test for each URI
120+ dynamicTests .add (dynamicTest ("Testing if URI namespace from the XML catalog: " + uriNameXmlCtlg + " matches the URI namespace from the local XSD file: " + targetNamespace , () -> {
121+ // Dummy test, the namespace check is done before
92122 }));
93123 }
94124 }
95125
126+ // Return the list of dynamic tests
96127 return dynamicTests ;
97128 }
98129}
0 commit comments