Loading ...
Sorry, an error occurred while loading the content.

Re: ampersand and friends

Expand Messages
  • Eric Amick
    ... XML doesn t care for ampersands (and a couple of other characters) in its data. The HTML::Entities module should be useful: use HTML::Entities; . . . #
    Message 1 of 6 , Oct 3, 2003
    • 0 Attachment
      On 3 Oct 2003 08:52:54 -0000, you wrote:


      >I've got a JWSDP-1.2 backend running
      >a JAXRPC service that exposes a WSDL.
      >I've got a frontend that uses PERL to
      >generate web pages and SOAP::Lite
      >to connect to the back end.
      >
      >Most of the time everything is fine. Once
      >in a while, somebody types in an
      >ampersand and blows something up.
      >I've isolated the problem down to what
      >appears to be an issue with encoding, but
      >I'm not sure. I have written a little program
      >that deterministically causes a fault
      >to occur. You can imagine that
      >in my "real code" the only thing that is
      >difference is that I am basically taking
      >input from the user, checking it for
      >some basic stuff and then putting it
      >into the function where below you see
      >hardcoded strings.
      >
      >#!/usr/bin/perl -w
      >
      >use strict;
      >use SOAP::Lite;
      >
      >use Data::Dumper;
      >
      >my $abc = SOAP::Lite->service("http://127.0.0.1:8080/abc/abc?WSDL");
      >
      ># this one works
      >@results = $abc->myfunc($token, 'Soccer');
      > print Dumper(@results);
      >
      ># this one does not work
      >@results = $abc->myfunc($token, 'a & b');
      > print Dumper(@results);

      XML doesn't care for ampersands (and a couple of other characters) in its
      data. The HTML::Entities module should be useful:

      use HTML::Entities;
      . . .

      # Encode "&", "<", ">", and "'"
      encode_entities($input_string, "&<>'");

      $input_string is modified in place by the encode_entities function by
      default. For more details, consult the module documentation.

      --
      Eric Amick
      Columbia, MD
    • Duncan Cameron
      ... True, but SOAP::Lite should be taking care of that. A simple test showed that an ordinary SOAP::Lite call (not WSDL) did handle the & correctly. How is the
      Message 2 of 6 , Oct 3, 2003
      • 0 Attachment
        --- Eric Amick <eric-amick@...> wrote:

        > XML doesn't care for ampersands (and a couple of other characters) in
        > its data. The HTML::Entities module should be useful:
        >
        True, but SOAP::Lite should be taking care of that.
        A simple test showed that an ordinary SOAP::Lite call (not WSDL) did
        handle the & correctly.
        How is the parameter described in WSDL?

        Duncan


        ________________________________________________________________________
        Want to chat instantly with your online friends? Get the FREE Yahoo!
        Messenger http://mail.messenger.yahoo.co.uk
      • Simon Lok
        Thanks for helping... here are what I believe to be the relevant fragments of the WSDL...
        Message 3 of 6 , Oct 3, 2003
        • 0 Attachment
          Thanks for helping... here are what I believe
          to be the relevant fragments of the WSDL...

          <complexType name="ArrayOfint">
          <complexContent>
          <restriction base="soap11-enc:Array">
          <attribute ref="soap11-enc:arrayType" wsdl:arrayType="int[]"/>
          </restriction>
          </complexContent>
          </complexType>

          <message name="abc_AddCompetitor">
          <part name="String_1" type="xsd:string"/>
          <part name="String_2" type="xsd:string"/>
          <part name="String_3" type="xsd:string"/>
          <part name="String_4" type="xsd:string"/>
          </message>

          <message name="abc_AddCompetitorResponse">
          <part name="result" type="tns:ArrayOfint"/>
          </message>

          <portType name="abc">
          <operation name="AddCompetitor" parameterOrder="String_1 String_2 String_3
          String_4">
          <input message="tns:abc_AddCompetitor"/>
          <output message="tns:abc_AddCompetitorResponse"/>
          </operation>
          </portType>

          <binding name="abcBinding" type="tns:abc">
          <operation name="AddCompetitor">
          <input>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
          use="encoded" namespace="urn:abc"/>
          </input>
          <output>
          <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
          use="encoded" namespace="urn:abc"/>
          </output>
          <soap:operation soapAction=""/>
          </operation>
          </binding>



          --- In soaplite@yahoogroups.com, Duncan Cameron <duncan_cameron2002@y...>
          wrote:
          > --- Eric Amick <eric-amick@c...> wrote:
          >
          > > XML doesn't care for ampersands (and a couple of other characters) in
          > > its data. The HTML::Entities module should be useful:
          > >
          > True, but SOAP::Lite should be taking care of that.
          > A simple test showed that an ordinary SOAP::Lite call (not WSDL) did
          > handle the & correctly.
          > How is the parameter described in WSDL?
          >
          > Duncan
          >
          >
          > ________________________________________________________________________
          > Want to chat instantly with your online friends? Get the FREE Yahoo!
          > Messenger http://mail.messenger.yahoo.co.uk
        • Simon Lok
          I hate suggesting that there is a bug in SOAP::Lite but I can t really think of anything else... here is a trivial JAVA web service that will demonstrate the
          Message 4 of 6 , Oct 3, 2003
          • 0 Attachment
            I hate suggesting that there is a bug
            in SOAP::Lite but I can't really think of
            anything else... here is a trivial JAVA
            web service that will demonstrate
            the problem:

            package helloservice;

            public class HelloImpl implements HelloIF {

            public String message = "Hello ";

            public String sayHello(String s) {
            return message + s;
            }

            }

            As you can see, all it does is take what it
            gets and returns what it got prepending
            the hardcoded string "Hello ".

            Here is a SOAP::Lite PERL program that
            calls that JAVA web service...

            #!/usr/bin/perl

            use SOAP::Lite;

            my $JavaHello = SOAP::Lite->service("http://localhost:8080/hello/hello?WSDL");

            print "a and b: ";
            print 'result: '.$JavaHello->sayHello("a and b");
            print "\n";

            print "a & b: ";
            print 'result: '.$JavaHello->sayHello("a & b");
            print "\n";

            print "a&b: ";
            print 'result: '.$JavaHello->sayHello("a&b");
            print "\n";

            print "a &a b: ";
            print 'result: '.$JavaHello->sayHello("a &a b");
            print "\n";

            print "a &am b: ";
            print 'result: '.$JavaHello->sayHello("a &am b");
            print "\n";

            print "a & b: ";
            print 'result: '.$JavaHello->sayHello("a & b");
            print "\n";

            print "a & b: ";
            print 'result: '.$JavaHello->sayHello("a & b");
            print "\n";


            Here is the output when I run the above program:

            a and b: result: Hello a and b
            a & b: result:
            a&b: result:
            a &a b: result:
            a &am b: result:
            a & b: result:
            a & b: result: Hello a & b


            As you can see the first and the last
            cases work. The really weird part is
            that the last one actually sends &amp;
            to the back end! At least that's what
            it appears to be doing because when the
            string gets returned to the front end, it
            comes back such. I would have thought that
            if SOAP::Lite were to work correctly, that
            the final one would simply return a string
            like 'Hello a & b'... not what you see above.
            This makes absolutely no sense. In the
            case of the five failures, there is a huge
            stack trace dumped on the back end s
            tarting with...

            SEVERE: deserialization error: XML parsing error:
            com.sun.xml.rpc.sp.ParseException:1: Next character must be ";"
            terminating reference to entity "amp"
            deserialization error: XML parsing error: com.sun.xml.rpc.sp.ParseException:1: Next
            character must be ";" termina
            ting reference to entity "amp"
            at
            com.sun.xml.rpc.encoding.SimpleTypeSerializer.deserialize(SimpleTypeSerializer.java:
            140)
            at
            com.sun.xml.rpc.encoding.AttachmentSerializer.deserialize(AttachmentSerializer.java:
            158)
            at
            com.sun.xml.rpc.encoding.ReferenceableSerializerImpl.deserialize(ReferenceableSeria
            lizerImpl.java:141)
            at
            helloservice.HelloIF_sayHello_RequestStruct__MyHello__SOAPSerializer.doDeserialize(
            HelloIF_sayHello_Re
            questStruct__MyHello__SOAPSerializer.java:41)


            CAUSE:

            XML parsing error: com.sun.xml.rpc.sp.ParseException:1: Illegal character or entity
            reference syntax
            at com.sun.xml.rpc.streaming.XMLReaderImpl.next(XMLReaderImpl.java:115)
            at
            com.sun.xml.rpc.encoding.SimpleTypeSerializer.deserialize(SimpleTypeSerializer.java:
            108)
            at
            com.sun.xml.rpc.encoding.AttachmentSerializer.deserialize(AttachmentSerializer.java:
            158)
            at
            com.sun.xml.rpc.encoding.ReferenceableSerializerImpl.deserialize(ReferenceableSeria
            lizerImpl.java:141)


            The contents of the WSDL are pretty straightforward:

            <?xml version="1.0" encoding="UTF-8"?>
            <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:Foo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://
            schemas.xmlsoap.org/wsdl/soap/" name="MyHelloService"
            targetNamespace="urn:Foo">
            <types/>
            <message name="HelloIF_sayGoodBye">
            <part name="String_1" type="xsd:string"/></message>
            <message name="HelloIF_sayGoodByeResponse">
            <part name="result" type="xsd:string"/></message>
            <message name="HelloIF_sayHello">
            <part name="String_1" type="xsd:string"/></message>
            <message name="HelloIF_sayHelloResponse">
            <part name="result" type="xsd:string"/></message>
            <portType name="HelloIF">
            <operation name="sayGoodBye" parameterOrder="String_1">
            <input message="tns:HelloIF_sayGoodBye"/>
            <output message="tns:HelloIF_sayGoodByeResponse"/></operation>
            <operation name="sayHello" parameterOrder="String_1">
            <input message="tns:HelloIF_sayHello"/>
            <output message="tns:HelloIF_sayHelloResponse"/></operation></portType>
            <binding name="HelloIFBinding" type="tns:HelloIF">
            <operation name="sayGoodBye">
            <input>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            use="encoded" namespace="urn:Foo"/></input>
            <output>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            use="encoded" namespace="urn:Foo"/></output>
            <soap:operation soapAction=""/></operation>
            <operation name="sayHello">
            <input>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            use="encoded" namespace="urn:Foo"/></input>
            <output>
            <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            use="encoded" namespace="urn:Foo"/></output>
            <soap:operation soapAction=""/></operation>
            <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/
            ></binding>
            <service name="MyHelloService">
            <port name="HelloIFPort" binding="tns:HelloIFBinding">
            <soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" location="http:/
            /localhost:8080/hello/hello"/></port></service></definitions>


            Thanks in advance for any ideas that you
            might have.
          • Simon Lok
            It appears that ampersand characters are not automatically encoded properly when using WSDLs... thanks to a tip about turning on tracing, I am able to include
            Message 5 of 6 , Oct 21, 2003
            • 0 Attachment
              It appears that ampersand characters are not
              automatically encoded properly when using
              WSDLs... thanks to a tip about turning on
              tracing, I am able to include the following dump
              SOAP message snippets...

              <SOAP-ENV:Body><namesp2:AddCompetitorType
              xmlns:namesp2="urn:ABC"><String_1
              xsi:type="xsd:string">176262029300358498510238664919063104555</
              String_1><String_2 xsi:type="xsd:string">a \& b</String_2></
              namesp2:AddCompetitorType></SOAP-ENV:Body>

              <SOAP-ENV:Body><namesp3:AddCompetitorType
              xmlns:namesp3="urn:ABC"><String_1
              xsi:type="xsd:string">176262029300358498510238664919063104555</
              String_1><String_2 xsi:type="xsd:string">a & b</String_2></
              namesp3:AddCompetitorType></SOAP-ENV:Body>

              Does anybody know how to turn on encoding
              of ampersands for WSDLs? I am also trying to run
              the same test using proxy and uri instead of
              using a WSDL but I am having some trouble
              getting that to work as well

              --SL
            Your message has been successfully submitted and would be delivered to recipients shortly.