Validating XSD itself - java

Could anyone please tell me how to validate an XSD file itself (not XML against XSD)? I have checked many forums and sites (including SO) and most of them refers some or the other online validator. But this is not a one-time check for us. Our application involves an XSL transformation using an XSD, so we need to determine whether the XSD to be used is itself in a valid format or not, as in, all the tags match, with a starting and a closing one. Certain tags aren't allowed as a child tag, etc. That's why we need a proper java code to achieve the same.
Any help would be highly appreciated.

You can validate an XSD file against the w3 XSD schema that can be found here.
Use the same validation techniques you validate any other XML file with an XSD file, only the source document would be your XSD file.

you can use xmllint for that:
xmllint --noout --dtdvalid http://www.w3.org/2001/XMLSchema.dtd my-schema.xsd

You can try javax.xml.validation package
SchemaFactory f = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema s = f.newSchema(new File("1.xsd"));
Schema.newSchema() API
Parses the specified File as a schema and returns it as a Schema

You can validate your XSD online here.
Just copy and paste your XSD here and click on validate Schema , it will give you the result.

Related

Validate XML against a catalog of values in other xml

I have a XML file with the following content:
<example>
<firstNode>
<someInfo>Hello</someInfo>
</firstNode>
<secondNode>
<myFlagColors>
<using>RED</using>
<using>WHITE</using>
<using>BLUE</using>
</myFlagColors>
</secondNode>
</example>
I have to check that every node <using>XYZ</using> has a value (like XYZ) coming from another XML like this one:
<colorCatalog>
<color>WHITE</color>
<color>BLACK</color>
<color>RED</color>
<color>GREEN</color>
<color>BLUE</color>
<color>YELLOW</color>
<color>PINK</color>
<color>ORANGE</color>
<color>CYAN</color>
</colorCatalog>
I donĀ“t like my current implementation made with java:
Convert every XML in a java Bean (using jaxb) and then use an iterator
to check if the value in the first bean in in the array of values of the second object.
My question: Is it possible to do this just by using xsd files? or any other way simpler than pure programming?
XML Schema Approach
If you can combine the XML documents then you could create an XSD that has a keyRef relationship between the 2 elements.
Validating the document against the schema would then highlight any errors.
If you can't combine the XML files easily then you could use xinclude (as long as your XSD parser supports it). Xerces for example supports it.

Is it possible to validate XML against schemas present in that XML file using Java?

So I have an XML that already has all the schemas specified in the root tag like this
<Waybill xmlns="urn:some:uri1"
xmlns:cac="urn:some:uri2"
xmlns:cbc="urn:some:uri3"
xmlns:ext="urn:some:uri4" xmlns:xxx="http://some.url.com">
Is it possible to validate my XML against these in the Java code in such a way that I don't have to repeat them in the Java code again?
All the examples I found so far require you to specify the url explicitly in the code
Try this: Validating XML against XSD
The magic seems to be in this: XMLConstants.W3C_XML_SCHEMA_NS_URI.

How do I validate an XML with a schema file that imports another schema file?

I want to validate XML files against this schema (that is inside the zip); it imports two other XSD files.
<import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation="xmldsig-core-schema.xsd"/>
<import namespace="http://www.w3.org/2001/04/xmlenc#"
schemaLocation="xenc-schema.xsd"/>
The 2 files are also available here:
http://www.forum-datenaustausch.ch/xmldsig-core-schema.zip
http://www.forum-datenaustausch.ch/xenc-schema.zip.
On validation, I get this error:
Src-resolve: Cannot Resolve The Name 'xenc:EncryptedData' To A(n) 'element Declaration' Component.
My validation/unmarshalling code looks like this (using moxy as a JAXB provider):
jaxbContext = JAXBContext.newInstance(type.getRequestType().getPackage().getName());
Unmarshaller um = jaxbContext.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/xsd/" + type.getXsdName())));
um.setSchema(schema);
root = um.unmarshal(new StreamSource(new ByteArrayInputStream(xmlData)), type.getRequestType());
Before you ask what does the type do: I wrote code that could import all types of invoices from http://www.forum-datenaustausch.ch/. But versions 4.3 and above use the two additional schema files. How can validate the XML files?
Have a look at the accepted answer for this post. Based on the little I can see in your post, and from what I can remember, the problem with the way you're loading the XSD has to do with the fact that doing it your way, the factory doesn't get a base uri, hence it can't apply its smarts to resolve references to the other two XSDs. I have to assume that your other two XSDs are also packed as resources in the same jar, in the same directory.
I have to admit that I am intrigued by the error message, which seems to imply the schema it loaded is valid, so it might be an XML issue; if the above doesn't help you, then you should consider posting the offending XML as well...
UPDATE: As per my comments, it is working as described. See code snippet below:
SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema compiledSchema = schemaFactory.newSchema(new SOTests().getClass()
.getClassLoader().getResource("generalInvoiceRequest_430.xsd"));
Validator validator = compiledSchema.newValidator();
try {
validator.validate(new StreamSource("D:\\...\\dentist_ersred_TG_430.xml"));
System.out.println("Valid.");
}
catch (SAXException ex) {
System.out.print("Not valid because..." + ex.getMessage());
}
You don't need to load more than the first XSD, and you shouldn't, since all the imports provide hints to the schema location.
The XSD files are all in the same directory in the generated jar, and they must be, since the relative URIs used for imports indicate same parent.
The program output with one of the files downloaded from here:
Valid.
And after introducing invalid content:
Not valid because...cvc-complex-type.2.4.a: Invalid content was found starting with element 'wrong'. One of '{"http://www.forum-datenaustausch.ch/invoice":processing}' is expected.
My recommendations to who reads this:
use getResource() to get an URL; as I've said above, a StreamResource doesn't have a base URI, hence relative references as per your xsd:import schemaLocation attribute cannot be de-referenced.
Let the schema/factory do the loading for you, when they're explicitly provided.
make sure that when provided, relative references match the folder structure in your jar file.
Similar problems here. I tried to import the GeneralInvoice into an integration Software.
Parser didn't like the DOCTYPE tag at the start of the import schemas. Solution: deleted the DOCTYPE section.
Parser didn't lke anyAttribute, anyURI etc. Solution: changed anyURI to string and removed other stuff by putting comments around.
Had to import the xenc and xwldsig xsd's first and then import GeneralInvoice in a second step.
Hope this helps

Validate a XSD file

I want to validate an XSD file (not XML). The approach i am using is to treat the XSD as any other XML file and use this www.w3.org/2001/XMLSchema.xsd as the schema.
I am using the following code:
String schemaLang = "http://www.w3.org/2001/XMLSchema";
SchemaFactory factory = SchemaFactory.newInstance(schemaLang);
Schema schema = factory.newSchema(new StreamSource("C:\\Users\\aprasad\\Desktop\\XMLSchema.xsd"));
Validator validator = schema.newValidator();
validator.validate(new StreamSource("shiporder.xsd"));
But i am getting the following error:
Failed to read schema document 'XMLSchema.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
Not sure what the error is as the file path is correct.
Please tell me the correct approach to validate an XSD file.
You need to have two additional files right beside XMLSchema.xsd. These are:
XMLSchema.dtd
datatypes.dtd
XMLSchema.xsd references these two files.
Right beside, so if XMLSchema.xsd is located at C:/XMLSchema.xsd then you have to have C:/XMLSchema.dtd and C:/datatypes.dtd.
SchemaFactory instances use (see SchemaFactory.setResourceResolver(LSResourceResolver)) by default an internal class called XMLCatalogResolver which implements LSResourceResolver. The former (I assume) looks for referenced files beside the referer.
If you look really hard then the cause of your SAXParseException is a FileNotFoundException that says the the system couldn't find the XMLSchema.dtd file.
Other than this, your code is OK (and your schema too).
According to the javadoc for the StreamSource class, if you use the constructor method that takes a String, that string needs to be a valid URI. For example, if you are trying to reference a local file, you may need to prefix the path with file:/. Alternatively, you can pass a File object to the constructor:
Schema schema = factory.newSchema(new File(new StreamSource("C:\\Users\\aprasad\\Desktop\\XMLSchema.xsd")));
In summary, it would be beneficial in this case to do some simple testing to rule out problems caused by your program not finding the necessary files, for example
File schemaFile1 = new File("C:\\Users\\aprasad\\Desktop\\XMLSchema.xsd");
File schemaFile2 = new File("shiporder.xsd");
assert schemaFile1.exists();
assert schemaFile2.exists();
I wonder what you are trying to achieve? If factory.newSchema(X) throws no exception, then X must be a valid schema(*). That seems a much more straightforward thing to do than validating against the schema for schema documents.
(*) the reverse isn't necessarily true of course: X might be valid against the schema for schema documents, but be invalid for other reasons, such as violating a UPA constraint.

Creating XML Schema from URL works but from Local File fails?

I need to validate XML Schema Instance (XSD) documents which are programmatically generated so I'm using the following Java snippet, which works fine:
SchemaFactory factory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema xsdSchema = factory.newSchema( // Reads URL every time...
new URL("http://www.w3.org/2001/XMLSchema.xsd"));
Validator xsdValidator = xsdSchema.newValidator();
xsdValidator.validate(new StreamSource(schemaInstanceStream));
However, when I save the XML Schema definition file locally and refer to it this way:
Schema schema = factory.newSchema(
new File("test/xsd/XMLSchema.xsd"));
It fails with the following exception:
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'file:/Users/foo/bar/test/xsd/XMLSchema.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
I've ensured that the file exists and is readable by doing exists() and canRead() assertions on the File object. I've also downloaded the file with a couple different utilities (web browser, wget) to ensure that there is no corruption.
Any idea why I can validate XSD instance documents when I generate the schema from the HTTP URL but I get the above exception when trying to generate from a local file with the same contents?
[Edit]
To elaborate, I've tried multiple forms of factory.newSchema(...) using Readers and InputStreams (instead of the File directly) and still get exactly the same error. Moreover, I've dumped the file contents before using it or the various input streams to ensure it's the right one. Quite vexing.
Full Answer
It turns out that there are three additional files referenced by XML Schema which must be also stored locally and XMLSchema.xsd contains an import statement whose schemaLocation attribute must be changed. Here are the files that must be saved in the same directory:
XMLSchema.xsd - change schemaLocation to "xml.xsd" in the "import" element for XML Namespace.
XMLSchema.dtd - as is.
datatypes.dtd - as is.
xml.xsd - as is.
Thanks to #Blaise Doughan and #Tomasz Nurkiewicz for their hints.
I assume you are trying to load XMLSchema.xsd. Please also download XMLSchema.dtd and datatypes.dtd and put them in the same directory. This should push you a little bit further.
UPDATE
Is XMLSchema.xsd importing any other schemas by relative paths that are not on the local file systen?
Your relative path may not be correct wrt your working directory. Try entering a fully qualified path to eliminate the possibility that the file can not be found.
org.xml.sax.SAXParseException: schema_reference.4: Failed to read
schema document 'file:/Users/foo/bar/test/xsd/XMLSchema.xsd', because
1) could not find the document; 2) the document could not be read; 3)
the root element of the document is not .

Categories

Resources