Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error using XJC with xml.xsd import: "Failed to read schema document 'xml.xsd'"

Tags:

java

xml

jaxb

xsd

I'm trying to run xjc on a Third-party's schema files (it's Amazon.com's product API). Well I'm running into trouble because with one of the files, default.xsd, xjc is borking on the following import (it's the first one right after the schema declaration):

<import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd" />

I'm not an expert on XML, but I thought xml.xsd was part of the "core" XML/XSD library and that XJC would know the details of this library by default. But when I run the task I get this error:

[WARNING] schema_reference.4: Failed to read schema document 'xml.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not . line 9 of file:/C:/temp/amazon/default.xsd

[ERROR] src-resolve: Cannot resolve the name 'xml:lang' to a(n) 'attribute declaration' component. line 119 of file:/C:/temp/amazon/default.xsd

I tried downloading the xml.xsd file from http://www.w3.org/2001/03/xml.xsd to the directory with these schema files and running the command again, but xml.xsd doesn't validate:

[ERROR] schema_reference.4: Failed to read schema document 'file:/C:/temp/amazon/xml.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not . unknown location

I was about to start going down the rabbit hole of why this wouldn't be validated, but decided to hold off since I think I'm missing something really simple or small. Do I need to manually include the xml.xsd import or am I missing something else?

The urls for the schema I am working with are currently here:

http://g-ecx.images-amazon.com/images/G/01/mwsportal/doc/en_US/products/default.xsd

and here

http://g-ecx.images-amazon.com/images/G/01/mwsportal/doc/en_US/products/ProductsAPI_Response.xsd

And I'm simply using:

xjc dirname together at once or xjc filename to try to parse them one-by-one

like image 607
IcedDante Avatar asked Sep 22 '15 00:09

IcedDante


2 Answers

You can use catalogs to fix this type of errors:

  • Assume one or more of your schemas reference a resource via invalid URL.
  • Find this resource (is probably available from some alternative location) and save it locally.
  • Create a catalog file to rewrite the URL. You can rewrite via namespace or via file location:
    PUBLIC "http://www.w3.org/XML/1998/namespace" "w3c/2001/03/xml.xsd"
    REWRITE_SYSTEM "http://www.w3.org/2001/03/xml.xsd" "w3c/2001/03/xml.xsd"
    (Local file location is w3c/2001/03/xml.xsd.)
  • Use it as xjc -catalog mycatalog.cat ...

You can do the same fo DTDs as well. I normally rewrite just "http://www.w3.org" -> "w3c" and keep the folder structure the same as on the server.

Using -nv is a good idea, works better with catalogs in any case:

  • https://github.com/highsource/maven-jaxb2-plugin/wiki/Catalogs-in-Strict-Mode

Links:

  • https://github.com/highsource/maven-jaxb2-plugin/wiki/Using-Catalogs
  • https://jaxb.java.net/guide/Fixing_broken_references_in_schema.html
  • http://blog.bdoughan.com/2011/10/jaxb-xjc-imported-schemas-and-xml.html
  • https://github.com/highsource/w3c-schemas (I'm the author of this one.)
like image 41
lexicore Avatar answered Oct 19 '22 11:10

lexicore


I downloaded your XSD files to mimic the error and indeed, when downloaded as is they give exactly the error you reported.

It wasn't immediately obvious what was happening. Yes, the XML namespace http://www.w3.org/XML/1998/namespace is special and reserved. You do not have to declare it for it to be in existence, but the xml.xsd file is used for Schema compliance, so that these predefined types are also defined in the XSD Schema, so that the types can be used in using schemas.

So my first thoughts were with the XML namespace needing to be declared as xmlns:xml="http://www.w3.org/XML/1998/namespace" (normally this is never needed) for XJC to behave normally, but that didn't change much.

After a bit going back and forth, I decided to run xjc with the option -nv, which turns of certain strict validation rules. This time, the error I received was a bit clearer and immediately pointed to the cause, and the obvious solution:

[ERROR] failed to retrieve 'file:/D:/Projects/xyz/XMLSchema.dtd': java.io.FileNotFoundException: D:\Projects\xyz\XMLSchema.dtd (The system cannot find the file specified) line 2 of file:/D:/Projects/xyz/xml.xsd

Apparently, XJC tries to download the DTD referenced by the DOCTYPE declaration:

<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" >

Actually, this isn't XJC, but the XML parser that precedes XSD validation. The XML parser used is a validating parser, which means it tries to find the DTD and if it cannot, it breaks. The error you received is not very helpful, but correct, as in XML terms, an XML file that points to a DTD is not a valid XML file (but it can be a well-formed XML file and non-validating XML processors, not to be confused with XSD schema validation, will simply load the XML).

Solution

However, the DTD is not required for the XML to be considered correct. You can either download the XMLSchma DTD, or, easier, simply remove that line and the processing will succeed, with or without the -nv switch.

like image 53
Abel Avatar answered Oct 19 '22 10:10

Abel