• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Create Schema from DOM Elements with multiple parts, Cannot resolve the name 'ns0:xxx'

 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

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.

 
Ranch Hand
Posts: 734
7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.>
 
Maarten Boekhold
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

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...
 
Maarten Boekhold
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:


<xs:schema
xmlns="http://www.abc.com/DetailsRequest"
xmlns:ns0="http://www.abc.com/Common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.abc.com/DetailsRequest"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:import namespace="http://www.abc.com/Common"/>
<xs:element name="DetailsRequest">
<xs:complexType>
<xs:sequence>
<xs:element ref="ns1:RequestBody"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RequestBody">
<xs:complexType>
<xs:sequence>
<!--xs:element name = "CustomerNumber" type="xs:string"/-->
<xs:element ref="ns0:CustomerNumber"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

<xs:schema
xmlns="http://www.abc.com/Common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.abc.com/Common"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="CustomerNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="AccountNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:schema>



with document:


<?xml version="1.0" encoding="UTF-8"?><fec:DetailsRequest xmlns:fec="http://www.abc.com/DetailsRequest">
<fec:RequestBody>
<fec1:CustomerNumber xmlns:fec1="http://www.abc.com/Common">12345</fec1:CustomerNumber>
</fec:RequestBody>
</fec:DetailsRequest>



fails with the error:


[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.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
...



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?
 
g tsuji
Ranch Hand
Posts: 734
7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
g tsuji
Ranch Hand
Posts: 734
7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

[1] First you make out a field in your class concerned which eventually the nested class Resolver would access it.


[2] 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.

[3] Then construct a nested class Resolver.

With the above, the validation of DetailsRequest and DetailsResponse and ErrorSchema should proceed with success.
 
Maarten Boekhold
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all, g tsuji,

I finally got around to implementing this, and I'm getting further now. I did have to add a special case to the LSResolver to load a local copy of the schema for the http://www.w3.org/XML/1998/namespace namespace.

I'm now getting stuck on the following: the WSDL defines namespace prefixes on the <wsdl:definitions> element, which are later used in the different schema elements. However those prefixes are NOT defined themselves on the schema elements, so I'm now getting the following error (using the same example as I started this thread with):



It doesn't seem possible to "pre-register" prefix->namespace mappings in any way, at least I haven't found it yet. So I'm wondering how to solve this. One idea I had was to first extract the "xmlns:XXX" attributes from the <wsdl:definitions> element (ignoring standard namespaces such as wsdl and soap, and probably xml:tns as well), and then add them to each extracted <xs:schema> element (if there's no existing xmlns:XXX attribute with the same name on that schema element).

Would there be a better solution for this?

edit: The above approach works! Still wondering if this is the best approach?

Maarten
 
reply
    Bookmark Topic Watch Topic
  • New Topic