Skip to content

Commit ffbf236

Browse files
committed
Pull request #152: Support for loading remote DTDs alongside XSDs
Merge in ITB/xml-validator from development to master * commit '2e6ea2e310eba81ec5426cee001a796d6a234f6a': Support for loading remote DTDs alongside XSDs
2 parents 9216be7 + 2e6ea2e commit ffbf236

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

xmlvalidator-common/src/main/java/eu/europa/ec/itb/xml/util/FileManager.java

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import org.apache.tika.Tika;
1111
import org.apache.tika.metadata.Metadata;
1212
import org.apache.xerces.impl.xs.XMLSchemaLoader;
13+
import org.apache.xerces.util.XMLCatalogResolver;
14+
import org.apache.xerces.xni.XMLResourceIdentifier;
15+
import org.apache.xerces.xni.XNIException;
1316
import org.apache.xerces.xs.StringList;
1417
import org.apache.xerces.xs.XSModel;
1518
import org.apache.xerces.xs.XSNamespaceItem;
@@ -250,23 +253,42 @@ public FileInfo getFileFromURL(File targetFolder, String url, String extension,
250253
*/
251254
private void retrieveSchemasForImports(String rootURI, File rootFolder, HttpClient.Version httpVersion) {
252255
XMLSchemaLoader xsdLoader = new XMLSchemaLoader();
253-
XSModel xsdModel = xsdLoader.loadURI(rootURI);
254-
XSNamespaceItemList xsdNamespaceItemList = xsdModel.getNamespaceItems();
255256
Set<String> documentLocations = new HashSet<>();
256-
for (int i=0; i<xsdNamespaceItemList.getLength(); i++) {
257-
XSNamespaceItem xsdItem = (XSNamespaceItem) xsdNamespaceItemList.get(i);
258-
StringList sl = xsdItem.getDocumentLocations();
259-
for(int k=0; k<sl.getLength(); k++) {
260-
if(!documentLocations.contains(sl.item(k))) {
261-
String currentLocation = (String)sl.get(k);
257+
// Use a custom resolver as this will handle XSDs as well as DTDs.
258+
xsdLoader.setEntityResolver(new XMLCatalogResolver() {
259+
@Override
260+
public String resolveIdentifier(XMLResourceIdentifier resourceIdentifier) throws IOException, XNIException {
261+
String expandedLocation = resourceIdentifier.getExpandedSystemId();
262+
if (expandedLocation != null && !documentLocations.contains(expandedLocation)) {
262263
try {
263-
getFileFromURL(rootFolder, currentLocation, httpVersion);
264-
documentLocations.add(currentLocation);
264+
getFileFromURL(rootFolder, expandedLocation, httpVersion);
265+
documentLocations.add(expandedLocation);
265266
} catch (IOException e) {
266267
throw new ValidatorException("validator.label.exception.loadingRemoteSchemas", e);
267268
}
268269
}
270+
return super.resolveIdentifier(resourceIdentifier);
271+
}
272+
});
273+
try {
274+
// Iterate also over the namespaces XSD imports and includes to ensure we haven't missed anything from the custom resolver.
275+
XSModel xsdModel = xsdLoader.loadURI(rootURI);
276+
XSNamespaceItemList xsdNamespaceItemList = xsdModel.getNamespaceItems();
277+
for (int i=0; i<xsdNamespaceItemList.getLength(); i++) {
278+
XSNamespaceItem xsdItem = (XSNamespaceItem) xsdNamespaceItemList.get(i);
279+
StringList sl = xsdItem.getDocumentLocations();
280+
for (int k=0; k<sl.getLength(); k++) {
281+
if (!documentLocations.contains(sl.item(k))) {
282+
String currentLocation = (String)sl.get(k);
283+
getFileFromURL(rootFolder, currentLocation, httpVersion);
284+
documentLocations.add(currentLocation);
285+
}
286+
}
269287
}
288+
} catch (ValidatorException e) {
289+
throw e;
290+
} catch (Exception e) {
291+
throw new ValidatorException("validator.label.exception.loadingRemoteSchemas", e);
270292
}
271293
}
272294

0 commit comments

Comments
 (0)