I am processing a WSDL document using wsdl4j and extract the schema elements from the wsdl:types section. WSDL4J returns this as org.w3c.dom.Element instances, and therefore I create my Schema instance using SchemaFactory.createSchema(DOMSource). I'm getting the following error:
Based on my google research, the normal way to resolve such errors is to use a custom LSResourceResolver. However, the resolveResource() method is supposed to return an instance of an LSInput, which implicitly assumes that the resources are available as unparsed XML.
How can I make this work? Code and sample WSDL follows...
Sample WSDL. Please note that with this reduced WSDL, I can make this work by reversing the order of the elements in the wsdlSchema array. However with the real WSDL (much larger, many more schema parts, >1300 lines), this does not work because the dependencies seem to be more complex. Also, the purpose of my code is to support arbitrary WSDL, which means I cannot make any assumptions in my code about the number, order and dependencies of the schema parts in the wsdl:types section.
This is a problem of document (schema here with validation) parsing (DOMSource) in-memory rather than a problem of wsdl4j. But, we can view it the other way of making an additional effort in the implementation of wsdl4j to overcome the "shortcoming"...
Since the evolution of xerces-j may be a bit slow for the needies, I would suggest you could do it by loading in-memory schema document twice like this.
You can save stack trace of the captured exception err to a log file if needed for inspection and debugging after the block. Noted the repassing does not sacrifice the needed exigence of the schema set being valid of its own. If it really is invalid at all, the eventual exception e is still being thrown. That part, wsdl4j is still doing a fine job such as namespace prefixes inherited from parent or ancestors are correctly captured making the schemas a coherent set.>
Joined: Jan 21, 2014
Wow, this works. I modified the logic a bit to better suite my purpose, and I also have to do the "reparsing" multiple times (needs to do 3 "parsings" in total to succeed), but the following works for me:
This is interesting. This suggests that the SchemaFactory instance maintains state, which I cannot find documented anywhere...
Joined: Jan 21, 2014
Hmmm, so creating the Schema instance works OK now, and even creating the Validator is fine. But the validation for the following still seems to fail:
[main] ERROR DynamicWS - validation failed
org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'fec1:CustomerNumber'. No child element is expected at this point.
If I take the same WSDL/Schema and XML document in SoapUI and do "Validate", it passes (note: since I mention SoapUI here, I must mention as well that I am really trying to validate a SOAP request that I receive using the SAAJ API, from which I extract just the request part of the SOAPBody. I've omitted that from the example above).
If I replace the element reference with a plain "element type=xs:string" (and change the ns reference in the XML document), the validation succeeds as well.
Makes me thing that although I now don't have any exceptions anymore while doing newSchema(), the schema in fact is still not read correctly?
Joined: Jan 18, 2011
Sorry for being late in responding... we have had some festivity in this part of the globe that kept me busy.
On general terms, I tend to agree with your followup posts. It is not a cure of a feasible validation procedure. It only demonstrates how to get around that early runtime error. I think there is no cause for me to insist on it. But mind you, even if the schemas were stored physically in a file system, with the loading of DOMSource with the order fairly randomly, the same validation error occurs at the end even though the early runtime error actually does not take place (curiously). So physical files rather than in-memory schemas do no better. The trouble is the unwarranted dependency on the order of xs loading that causes the pain. And it may as well be some major bugs that I can't supply the source without digging through some documents... Image how it is desirable and reasonable to run a DOMSource setup of the schema object and that the validation process would search through the grammar pool automatically below the surface as defined by the collection of schemas supplied. That is a rational expected but unfortunately the framework leaves so much to desire...
One can imagine an algorithm in view of constructing all the permutations of the schema sources (here four). It is not a hugh number (24) yet to find the one that load successfully in the first go. But, I can image a configuration where even the labour permutation does not find a acceptable sequence. Besides, that seems hacky indeed. Better have the xerces-j develop a solution to allow the approach using DOMSource to work... but that can be eternity.
I can image some other preprocessing to make thing happen... but again very specific code for some specific configuration. Not really a longer term solution.
I could supply you with a proper LSResourceResolver approach to resolve the resource re-direction problem. It depends on Dom level 3 LS support : that's no problem as of now with xerces-j. The schema loading line would look quite different. I would put some effect in the presentation of it in this case as it can be very laborious for a general purpose construction and it won't be that instructive.
That is as for now, I will come back on this soon.
Joined: Jan 18, 2011
This is how I would phase in your existing code. I would limit myself to the case where all the schema elements each has a unique targetNamespace : this simplify the consideration and it is indeed the case here. It is also somehow still with a reasonably large range of applicability.
 First you make out a field in your class concerned which eventually the nested class Resolver would access it.
 Then in the testWSDLSchema method in your first post, the lines starting from #7 to #25, I replace with this. Some lines which no long appear hereinbelow are meant to be taken out, meaning that I don't need them.
 Then construct a nested class Resolver.
With the above, the validation of DetailsRequest and DetailsResponse and ErrorSchema should proceed with success.