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

940Accessing XML Data attributes (was Re: Newbie question)

Expand Messages
  • Silly Yahoo Readers
    Oct 22, 2001
      Paul,

      Sometime around 3 AM I started getting it... ;-) Thanks for your
      input in this forum, etc.

      Now I'm using type(xml =>...) and am able to get the elements (not
      the attributes) of the XML record. Is there a way to get the
      attributes, too? I can get at the elements with a simple

      return "root__child: $_[0]->{root}->{child}";

      How do I access the attributes in the XML Data?

      Here's my simple server:

      #!/usr/local/bin/perl -w
      use SOAP::Transport::HTTP;

      SOAP::Transport::HTTP::CGI
      -> dispatch_to('ONE')
      -> handle;

      package ONE;

      sub dump {
      my ($class, @params) = @_;
      use Data::Dumper;
      #return Dumper(@params); # Dumps DOM tree, no attributes
      return $params[0]->{ROOT}->{some}->{node}; # access elements
      }

      exit;

      --- In soaplite@y..., Paul Kulchenko <paulclinger@y...> wrote:
      > Hi, Robert!
      >
      > SOAP::Data->type(xml => ...) is the way to send XML fragment that
      > will look like XML on wire. SOAP::Lite doesn't do any validation in
      > this case, so it's quite possible that generated XML (by itself or
      in
      > combination with SOAP envelope) is invalid. ->type(base64 => ...)
      > doesn't have this problem and always generate valid XML. You may see
      > what do you have on wire if you switch on debug info on client side
      > with ->on_debug(sub{print@_}).
      >
      > If you insert XML as a fragment I do not recommend you to use
      > unqualified 'id' attributes, because they may interfere with 'id'
      > attribute that is used by SOAP itself (yet you'll be able to access
      > that attribute).
      >
      > > > 4) What's the best way to send/receive a well-formed
      > > > and x-schema validating XML data record for import
      > > > into a local database?
      > I would say base64 is the best way to go (esp. if XML processing is
      > required on another side anyway), because if you encode XML as a
      > fragment you'll need to write custom deserializer to process your
      > data. Let me know if you have any questions.
      >
      > Best wishes, Paul.
      >
      > --- Silly Yahoo Readers <theonetowhommyrefers@y...> wrote:
      > > Since writing the below I found the SOAP::Data->type(...) thingy
      > > (attribute? directive?) and played around with a few settings.
      When
      > > I
      > > specify the default (base64) my server finds and parses the
      > > message.
      > > When I specify 'xml' I get the following error:
      > >
      > > Fault: SOAP-ENV:Server, not well-formed (invalid token) at line
      1,
      > > column 4, byte 4 at /usr/local/lib/perl5/site_perl/5.6.1/i686-
      > > linux/XML/Parser.pm line 185
      > >
      > > *Sigh* Help?
      > >
      > > --
      > > Robert Taylor
      > >
      > > --- In soaplite@y..., Robert Taylor <theonetowhommyrefers@y...>
      > > wrote:
      > > > I created my first data-based connected SOAP
      > > > client/server combination using SOAP-Lite. Now I want
      > > > my business partner to be able to use my HTTPS/CGI
      > > > SOAP server and have run into a problem.
      > > >
      > > > My goal is to receive an XML record for import into my
      > > > (MySQL) database. The partner defined the record but
      > > > I'm defining the SOAP service.
      > > >
      > > > A few questions:
      > > >
      > > > 1) If the @lines in "$soap->store(@lines)" contains a
      > > > well-formed and x-schema validated XML file, why is
      > > > the payload (right term?) serialized?
      > > >
      > > > 2) Related to (1) -- the data sent to the server is
      > > > encoded (base 64?). Must it be?
      > > >
      > > > 3) My partner is coding his own client (not using
      > > > SOAP::Lite, but something in C++ on an MS platform --
      > > > not using .NET tools either). He's sending basically
      > > > handcrafted SOAP messages with the Body a simple XML
      > > > file. When I showed him the output of my client.cgi
      > > > (below) using the "on_debug" method he balked at the
      > > > Base64 and <c-gensym6 xsi:type="xsd:int"> wrappers on
      > > > the XML file.
      > > >
      > > > Pretend my XML Data looks like this:
      > > >
      > > > <Test>
      > > > <Question id="1" type="short answer"><text>What is
      > > > the correct spelling of your name?</text></Question>
      > > > <Question id="2" type="multiple choice"><text>What
      > > > is your gender?</text>
      > > > <option id="A">Male</option>
      > > > <option id="B">Female</option>
      > > > <option id="C">Cowboy Neal</option>
      > > > </Question>
      > > > </Test>
      > > >
      > > >
      > > > Why is it encoded with the <c-gensym3...> tags?
      > > > (Dumped using on_debug)?
      > > >
      > > > POST https://xxx.xxx.xxx.xxx/cgi-bin/server.cgi
      > > > Accept: text/xml
      > > > Accept: multipart/*
      > > > Content-Length: 1434
      > > > Content-Type: text/xml; charset=utf-8
      > > > SOAPAction: "https://xxx.xxx.xxx.xxx/ONE#store"
      > > >
      > > > <?xml version="1.0" encoding="UTF-8"?>
      > > > <SOAP-ENV:Envelope
      > > > xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
      > > >
      > > SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
      > > > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
      > > > xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
      > > > xmlns:xsd="http://www.w3.org/1999/XMLSchema"
      > > > >
      > > > <SOAP-ENV:Body
      > > > >
      > > > <namesp1:newrx
      > > > xmlns:namesp1="https://xxx.xxx.xxx.xxx/ONE"
      > > > >
      > > > <c-gensym3 xsi:type="xsd:string"
      > > > ><?xml version="1.0" encoding="UTF-8"?>
      > > > </c-gensym3>
      > > > <c-gensym5 xsi:type="xsd:string"
      > > > ><Test>
      > > > </c-gensym5>
      > > > <c-gensym7 xsi:type="xsd:string"
      > > > > <Question id="1" type="short
      > > > answer"><text>What is the correct spelling of your
      > > > name?</text></Question>
      > > > </c-gensym7>
      > > > <c-gensym9 xsi:type="xsd:string"
      > > > > <Question id="2" type="multiple
      > > > choice"><text>What is your gender?</text>
      > > > </c-gensym9>
      > > > <c-gensym11 xsi:type="xsd:string"
      > > > > <option id="A">Male</option>
      > > > </c-gensym11>
      > > > <c-gensym13 xsi:type="xsd:string"
      > > > > <option id="B">Female</option>
      > > > </c-gensym13>
      > > > <c-gensym15 xsi:type="xsd:string"
      > > > > <option id="C">Cowboy Neal</option>
      > > > </c-gensym15>
      > > > <c-gensym17 xsi:type="xsd:string"
      > > > > </Question>
      > > > </c-gensym17>
      > > > <c-gensym19 xsi:type="xsd:string"
      > > > ></Test>
      > > > </c-gensym19></namesp1:newrx></SOAP-ENV:Body></SOAP-
      ENV:Envelope>
      > > >
      > > > 4) What's the best way to send/receive a well-formed
      > > > and x-schema validating XML data record for import
      > > > into a local database?
      > > >
      > > > Here's my client:
      > > >
      > > > #!/usr/local/bin/perl -w
      > > > # SOAP Client -> simulates XML Data transfer via
      > > > # SOAP.
      > > > use SOAP::Lite;
      > > >
      > > > my $server =
      > > > 'https://xxx.xxx.xxx.xxx/cgi-bin/server.cgi';
      > > >
      > > > #==========================
      > > > # Read in XML as if stream
      > > > #--------------------------
      > > > open (FILE, "<data.xml");
      > > > my @lines = <FILE>;
      > > > close(FILE);
      > > >
      > > > #--------------------------
      > > > # Setup call
      > > > #--------------------------
      > > > my $soap = SOAP::Lite
      > > > -> uri('https://xxx.xxx.xxx.xxx/ONE')
      > > > -> proxy($server)
      > > > ;
      > > > my $result = $soap->store(@lines);
      > > >
      > > > #processing of $result excluded
      > > >
      > > >
      > > > My server is simple:
      > > >
      > > > #!/usr/local/bin/perl -w
      > > > # SOAP Server - stores XML data in database
      > > > use SOAP::Transport::HTTP;
      > > >
      > > > SOAP::Transport::HTTP::CGI
      > > > -> dispatch_to('ONE')
      > > > -> handle;
      > > >
      > > > package ONE;
      > > >
      > > >
      > > > sub store {
      > > > my ($self, @passed) = @_;
      > > > use XML::EasyOBJ; # yep, I'm using this module
      > > > #=========================
      > > > # Force input to tmp file
      > > > #
      > > > # *Sigh* couldn't find a
      > > > # way to parse streamed
      > > > # data with EasyOBJ...
      > > > #-------------------------
      > > > use IO::File;
      > > > use POSIX qw(tmpnam);
      > > > use File::Copy;
      > > > use Time::HiRes qw(gettimeofday);
      > > >
      > > > my ($fname,$fh);
      > > > do { $fname = tmpnam() }
      > > > until $fh = IO::File->new($fname,
      > > > O_RDWR|O_CREAT|O_EXCL);
      > > >
      > > > foreach (@passed) {
      > > > print $fh $_;
      > > > }
      > > >
      > > > close($fh);
      > > >
      > > > my $bak_dir = '../backups/';
      > > > my $ext = gettimeofday;
      > > > copy ($fname,"${bak_dir}store.$ext")
      > > > || warn "Could not copy $fname: $!";
      > > > #=========================
      > > >
      > > >
      > > > #=========================
      > > > # Process XML with EasyOBJ
      > > > #-------------------------
      > > >
      > > > #-------------------------------------
      > > > # Use temp file for EasyOBJ processing
      > > > #-------------------------------------
      > > > my $doc = new XML::EasyOBJ($fname)
      > >
      > === message truncated ===
      >
      >
      > __________________________________________________
      > Do You Yahoo!?
      > Make a great connection at Yahoo! Personals.
      > http://personals.yahoo.com
    • Show all 9 messages in this topic