Skip Menu |

This queue is for tickets about the XML-Compile-SOAP CPAN distribution.

Report information
The Basics
Id: 79786
Status: resolved
Priority: 0/
Queue: XML-Compile-SOAP

People
Owner: Nobody in particular
Requestors: mcdave [...] stanford.edu
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 2.29
Fixed in: 2.30



Subject: Some namespace declarations confuse "explain"
Two of the attached WSDL files work just fine, but the one named "simple_bad" confuses XML::Compile::WSDL11->explain. Running the attached script should "explain" the testOp method three times, but instead the simple_bad WSDL gives error: no prefix known for namespace http://www.example.com/otherSchema The offending line seems to be <wsdl:part name="testInReq" element="ns:testDetails" xmlns:ns="http://www.example.com/otherSchema"/> That's legal, right? The "ns" in the QName isn't ambiguous or anything? If "http://www.example.com/otherSchema" is given a name somewhere else in the file, explain works. It's interesting to note that "compile" and "call" work fine in all cases; it's just "explain" that is a problem. So it's not like you can't use the WSDL with the funny namespaces. You just can't get explain to help. This example was inspired by something on the mailing list last month, where the advice was to examine the output of "explain" but that just caused more errors.
Subject: simple_good.wsdl
Download simple_good.wsdl
application/octet-stream 1.5k

Message body not shown because it is not plain text.

Subject: wsdl_test_explain.pl
#!/usr/bin/perl use strict ; use warnings ; use Data::Dumper ; use XML::Compile::WSDL11; use XML::Compile::SOAP11; use XML::Compile::Transport::SOAPHTTP; # use Log::Report mode => 'DEBUG'; # enable debugging foreach my $w (qw/simple_bad.wsdl simple_good.wsdl simple_good2.wsdl/) { print "Examining $w\n" ; eval { tryWSDL($w) ; } ; warn $@ if $@ ; print '-x' x 10, "\n" ; } sub tryWSDL { my ($wsdlfile) = @_ ; my $wsdl = XML::Compile::WSDL11->new($wsdlfile); # warn "Compiling" ; my $call = $wsdl->compileClient( 'testOp' , transport_hook => \&fake_server ); # warn "Executing" ; my ($answer, $trace) = $call->( { testInReq => {} } ) ; print "Answer is " . Dumper($answer) ; # warn "Explaining" ; print $wsdl->explain( 'testOp', PERL => 'INPUT', recurse => 1, ); } sub fake_server($$) { my ($request, $trace) = @_; my $content = $request->decoded_content; $content =~ s/></>\n</g; # print $content; my $answer = <<_ANSWER; <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x0="boo"> <SOAP-ENV:Body> <x0:hasVersion>3.14</x0:hasVersion> </SOAP-ENV:Body> </SOAP-ENV:Envelope> _ANSWER use HTTP::Response; HTTP::Response->new ( HTTP::Status::RC_OK , 'answer manually created' , [ 'Content-Type' => 'text/xml' ] , $answer ); }
Subject: simple_bad.wsdl
Download simple_bad.wsdl
application/octet-stream 1.5k

Message body not shown because it is not plain text.

Subject: simple_good2.wsdl
Download simple_good2.wsdl
application/octet-stream 1.5k

Message body not shown because it is not plain text.

On Fri Sep 21 20:06:20 2012, mcdave@stanford.edu wrote: Show quoted text
> Two of the attached WSDL files work just fine, but the one named > "simple_bad" confuses XML::Compile::WSDL11->explain. Running the > attached script should "explain" the testOp method three times, but > instead the simple_bad WSDL gives
I've run into this as well. I can provide a WSDL/XSD offline, as they can't be made public. To quote mcdave, who looked at this with me on irc: The wsdl contains: <wsdl:part name="head" element="xsns:Foo" xmlns:xsns="http://url/v2"/> At http://schemas.xmlsoap.org/wsdl/, I read that "wsdl:part"'s "element" attribute is of type "xs:QName", which I understand to be a qualified name, and "xsns:Foo" makes perfect sense... as long as "xsns" makes sense as a namespace. And it's being declared as "http://url/v2" right there in the element. Is it legal to declare a namespace within an element and use it in a attribute directly? I can't tell what the "scope" of an xmlns declaration is supposed to be, but evidently XML::Compile does not believe it to include the values of attributes in the same element.
Subject: Re: [rt.cpan.org #79786] Some namespace declarations confuse "explain"
Date: Fri, 28 Sep 2012 00:39:03 +0200
To: Karen Etheridge via RT <bug-XML-Compile-SOAP [...] rt.cpan.org>
From: NLnet webmaster <webmaster [...] nlnet.nl>
* Karen Etheridge via RT (bug-XML-Compile-SOAP@rt.cpan.org) [120927 21:10]: Show quoted text
> I've run into this as well. I can provide a WSDL/XSD offline, as they > can't be made public.
please. Show quoted text
> To quote mcdave, who looked at this with me on irc: > The wsdl contains: > <wsdl:part name="head" element="xsns:Foo" xmlns:xsns="http://url/v2"/> > > At http://schemas.xmlsoap.org/wsdl/, I read that "wsdl:part"'s > "element" attribute is of type "xs:QName", which I understand to be a > qualified name, and "xsns:Foo" makes perfect sense... as long as "xsns" > makes sense as a namespace. And it's being declared as "http://url/v2" > right there in the element.
If I look at the code, in XML/Compile/Schema/BuiltInTypes.pm, I see $builtin_types{QName} = { parse => sub { my ($qname, $node) = @_; $qname =~ s/\s//g; my $prefix = $qname =~ s/^([^:]*)\:// ? $1 : ''; $node = $node->node if $node->isa('XML::Compile::Iterator'); ---> my $ns = $node->lookupNamespaceURI($prefix) || ''; pack_type $ns, $qname; This should resolve the namespace. No idea (yet) why that doesn't work. Show quoted text
> Is it legal to declare a namespace within an element and use it in a > attribute directly? I can't tell what the "scope" of an xmlns > declaration is supposed to be, but evidently XML::Compile does not > believe it to include the values of attributes in the same element.
Yes, legal. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Subject: Re: [rt.cpan.org #79786] Some namespace declarations confuse "explain"
Date: Fri, 28 Sep 2012 00:55:41 +0200
To: Karen Etheridge via RT <bug-XML-Compile-SOAP [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* NLnet Webmaster (webmaster@nlnet.nl) [120928 00:39]: Show quoted text
> If I look at the code, in XML/Compile/Schema/BuiltInTypes.pm, I see > $builtin_types{QName} = > { parse => > sub { my ($qname, $node) = @_; > $qname =~ s/\s//g; > my $prefix = $qname =~ s/^([^:]*)\:// ? $1 : ''; > > $node = $node->node if $node->isa('XML::Compile::Iterator'); > ---> my $ns = $node->lookupNamespaceURI($prefix) || ''; > pack_type $ns, $qname;
This works correctly... So I am wondering why it does not work in XML::Compile... use XML::LibXML; my $dom = XML::LibXML->load_xml(string => <<__XML); <wsdl:part xmlns:wsdl="/tmp/xx" name="head" element="xsns:Foo" xmlns:xsns="http://url/v2"/> __XML my $root = $dom->documentElement; print $root->lookupNamespaceURI('xsns') || '', "\n"; my $el = $root->getAttributeNode('element'); print $el->lookupNamespaceURI('xsns') || '', "\n"; -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
From: mcdave [...] stanford.edu
On Thu Sep 27 18:55:55 2012, Mark@Overmeer.net wrote: Show quoted text
> * NLnet Webmaster (webmaster@nlnet.nl) [120928 00:39]:
> > If I look at the code, in XML/Compile/Schema/BuiltInTypes.pm, I see > > $builtin_types{QName} = > > { parse => > > sub { my ($qname, $node) = @_; > > $qname =~ s/\s//g; > > my $prefix = $qname =~ s/^([^:]*)\:// ? $1 : ''; > > > > $node = $node->node if $node->isa('XML::Compile::Iterator'); > > ---> my $ns = $node->lookupNamespaceURI($prefix) || ''; > > pack_type $ns, $qname;
> > This works correctly... So I am wondering why it does not work in > XML::Compile... >
I think the problem is just that XML::Compile::Cache lost track of the prefix momentarily during "explain", and "$schema->prefixed($value)" returned an error instead of undef, so $schema->prefixed($value) || $value didn't behave as expected. With the attached little change to XML::Compile::SOAP11::Operation, explain stopped crashing on my test case. It's not a solution, just an experiment. The output for the "simple_bad.wsdl" case turned into the text below. What was interesting to me is that, once it got past the initial hurdle of not crashing when describing the body, the recursive part down in XML::Compile::Translate::Template "toPerl" knew enough to make up the prefix "x0" for the missing namespace. Then I got lost and couldn't figure out a coherent explanation for why it worked in one case but not another. dave -- ... # The details of the types and elements are attached below. # Body part 'testInReq' is element {http://www.example.com/otherSchema}testDetails my $testInReq = {}; ... #-------------------------------------------------------------- $testInReq = # Describing simple x0:testDetails # {http://www.example.com/otherSchema}testDetails # xmlns:x0 http://www.example.com/otherSchema # is a xs:anyType "anything" ; Show quoted text
> use XML::LibXML; > > my $dom = XML::LibXML->load_xml(string => <<__XML); > <wsdl:part xmlns:wsdl="/tmp/xx" name="head" element="xsns:Foo" > xmlns:xsns="http://url/v2"/> > __XML > > my $root = $dom->documentElement; > print $root->lookupNamespaceURI('xsns') || '', "\n"; > > my $el = $root->getAttributeNode('element'); > print $el->lookupNamespaceURI('xsns') || '', "\n"; >
Subject: tkt79786_clue.patch
diff --git a/lib/XML/Compile/SOAP11/Operation.pm b/lib/XML/Compile/SOAP11/Operation.pm index f236142..05196d7 100644 --- a/lib/XML/Compile/SOAP11/Operation.pm +++ b/lib/XML/Compile/SOAP11/Operation.pm @@ -322,15 +322,16 @@ sub explain($$$@) BODY_PART: foreach my $part ( @{$def->{body}{parts} || []} ) { my $name = $part->{name}; my ($kind, $value) = $part->{type} ? (type => $part->{type}) : (element => $part->{element}); - my $type = $schema->prefixed($value) || $value; + my $type = $schema->prefixFor($value) ? + $schema->prefixed($value) : $value ; push @main, '' , "# Body part '$name' is $kind $type" , ($kind eq 'type' && $recurse ? "# See fake element '$name'" : ()) , "my \$$name = {};"; push @struct, " $name => \$$name,"; $recurse or next BODY_PART;
Subject: Re: [rt.cpan.org #79786] Some namespace declarations confuse "explain"
Date: Sat, 29 Sep 2012 01:52:22 +0200
To: David Tindall Mcmath via RT <bug-XML-Compile-SOAP [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* David Tindall Mcmath via RT (bug-XML-Compile-SOAP@rt.cpan.org) [120928 15:10]: Show quoted text
> I think the problem is just that XML::Compile::Cache lost track of the > prefix momentarily during "explain", and "$schema->prefixed($value)" > returned an error instead of undef, so > > $schema->prefixed($value) || $value
Ah, it tries to do a reverse translation there... You fix is sound, thanks! -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
I've just tested mcdave's patch and confirmed it fixes my namespacing issue as well (as transmitted to Mark in private email). Thank you very much!
fixed in 2.30