I have a wsdl that contains request and response elements:
<xsd:element name="someRequest" type="ns:SomeRequest"/>
<xsd:element name="someResponse" type="ns:SomeResponse"/>
This wsdl imports a few xsd's, which contain, among others, these complexTypes:
<xsd:complexType name="SomeRequest">
...
</xsd:complexType>
<xsd:complexType name="SomeResponse">
...
</xsd:complexType>
I want to validate an xml against this wsdl, but I can't get it to work. I'm basically using the method described on http://actimem.com/java/jaxb-validation/#Marshalling_Validation, by marshalling the object and setting a Schema and EventHandler.
If I set the Schema to the xsd, it won't validate because there's no element in the xsd. This is pretty logical, I get the same with other tools. When I use the wsdl as Schema, I get this error because of inline documentation:
s4s-elt-character: Non-whitespace characters are not allowed in schema elements other than 'xs:appinfo' and 'xs:documentation'.
Is there any way to get this to validate?
Since I'm working on existing projects (currently using Xmlbeans instead of JAXB) with a set workflow, I have to work with a few constraints:
I've tried transforming the schema to add the element manually, but I can't find a way to do it on an existing Schema object. If I do this through DOM manipulation, I get the new schema as a String object, which won't parse into a Schema because the imported xsd's can't be found.
If I copy the xsd's from the jar to the project, I can transform them and get the validation to succeed, but I don't really like this solution. If there's no other way, I'll revert to that, but I would like to find a solution that requires as little work as possible when reusing this method and is the least prone to errors. Other developers will use this code and 1 validate method without needing extra steps to work would be perfect.
I ran into basically this problem before and didn't find a solution then, either. But before, the complexType wasn't the root element and I could just wrap it into other objects until I found an object that was represented as element in the xsd.
You may consider to look at javax.xml.validation.Validator
class.
There is a way to create it for schema in the WSDL document and then you will have your someRequest
element you can validate against that schema.
code may look like:
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.ErrorHandler;
...
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
String testXml = "{your XML document}"
Document domDoc = docBuilder.parse(new ByteArrayInputStream(testXml.getBytes()));
Source inputSource = new DOMSource(domDoc);
Validator validator = requestedSchema.newValidator();
MySchemaValidationErrorHandler errHandler = new MySchemaValidationErrorHandler();
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema requestedSchema = schemaFactory.newSchema({DOMSource from WSDL document/types/xsd:schema node}));
validator.setErrorHandler(errHandler);
validator.validate(inputSource);
Note that you need to have your own implementation of org.xml.sax.ErrorHandler
interface where all warnings and errors will be collected during validation.
In general it is not hard to make all of that. You just need
schemaFactory.newSchema(...)
methodorg.xml.sax.ErrorHandler
interface where all errors be collected. It is very simplePS. Usually I create needed Schemas once and keep them in the Map. Just keep in mind - Validator is not thread safe.
of course you can use any other javax.xml.transform.Source
implementations, not only DOMSource
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With