Adding soap element attributes

Hi,

I have a question that I hope will be simple for someone to answer.

I am using soap4r to write a simple library to consume web services from
an application. The application does not include a WSDL document, so I
have to write everything by hand.

The application requires attributes in certain elements of the soap
request, and I am having a little trouble figuring out how to do this.
So far, a portion of my test code looks like this:

driver = SOAP::RPC::Driver.new(endpoint, ‘urn:namespace’)
driver.add_method_as(‘get_account’, ‘GetAccountRequest’, ‘account’)
get_account = driver.get_account(‘[email protected]’)

which produces this:

<n2:GetAccountRequest xmlns:n2=“urn:namespace”
env:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
[email protected]
</n2:GetAccountRequest>

but I need the soap request to look like this:

<n2:GetAccountRequest xmlns:n2=“urn:namespace”
env:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
[email protected]
</n2:GetAccountRequest>

with the by=“name” attribute in the account element.

I’ve been experimenting with SOAP::Mapping::Registry to achieve this,
but I am not sure how it would be done, or even if this is the correct
approach to take. If anyone can offer any assistance, it would be
appreciated.

Thanks,
Andrew

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Andrew T. wrote:

I am using soap4r to write a simple library to consume web services from
an application. The application does not include a WSDL document, so I
have to write everything by hand.

Unlucky.

The application requires attributes in certain elements of the soap
request, and I am having a little trouble figuring out how to do this.
So far, a portion of my test code looks like this:

driver = SOAP::RPC::Driver.new(endpoint, ‘urn:namespace’)
driver.add_method_as(‘get_account’, ‘GetAccountRequest’, ‘account’)
get_account = driver.get_account(‘[email protected]’)

You need to set up a request object by yourself.

ele = SOAP::SOAPString.new(‘[email protected]’)
ele.elename = XSD::QName.new(nil, ‘account’)
ele.extraattr[XSD::QName.new(nil, ‘by’)] = ‘name’
driver.get_account(ele)

It must be a hard work when it comes to a complex request object. You
can write a WSDL from service definition first.

Regards,
// NaHi

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)

iQEVAwUBRUSS0B9L2jg5EEGlAQINDwf9E+xnyx8w7Ztbk8j6HEoiYyzHd2sxKoDm
T9GCqS2tSiu293pnqZg+daNhoufuRWXD7tOZvlByhz1nW3MqdbbQYBD4rjLPKQPy
06Sd08W6DSP/axgGgtATlHPEmotU/GYmi6s+J7Mf5VSx5Lh1ON+W3FZTfyV8YpWV
ui0JvcR0I0byjiso7E0xvOypXR1eISihiLFw1rpltk0LQyRGWt7pgmlBbB8wOsHn
+mlgRFCXOCKMExKs0tfVFTy0Szi4NHBHb58UMJuDCWj7ATGrUJo68FTd1ywJY5Th
EcdOPEiOaelg+VPDvhK0dByFjk467G6jFNjTPFMmFL/oohyzl8Zz6w==
=0Eph
-----END PGP SIGNATURE-----

Thanks Hiroshi, that got me started. Soap4r is great, I just wish this
app had a WSDL!

I may consider writing a WSDL for this application, but for now I only
need a subset of fucntionality. The request objects are all pretty
simple, but I am having trouble accessing data from the response
objects.

After calling:

get_account = driver.get_account(‘[email protected]’)

The raw XML response for this command looks something like this:

value1 value2 value3 ...

I need to access the key/value pairs in the a attributes, but
get_account.account.a simply returns an array of [value1, value2,
value3, …] and seems to ignore the attributes. Many response objects
for this app take this form, so it would be nice to be able to create a
hash, or ruby object dynamically based on the key/values.

Can I access the raw response XML somehow, or is there a better way to
do this?

The app I am using is Zimbra, in case anyone has any experience or
advice for use with Soap4r.

Thanks again,
Andrew

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Andrew T. wrote:

I need to access the key/value pairs in the a attributes, but
get_account.account.a simply returns an array of [value1, value2,
value3, …] and seems to ignore the attributes. Many response objects
for this app take this form, so it would be nice to be able to create a
hash, or ruby object dynamically based on the key/values.

You need to define the service as a document service when you want to
handle XML attribute. Try the following.

/	/	/

require ‘soap/rpc/driver’

ns = ‘urn:namespace’
soapaction = nil

driver = SOAP::RPC::Driver.new(nil, ns)
driver.add_document_method(‘get_account’, soapaction,
XSD::QName.new(ns, ‘GetAccountRequest’),
XSD::QName.new(ns, ‘GetAccountResponse’))

driver.test_loopback_response << <<XML
<env:Envelope xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/”>
env:Body


value1
value2
value3


</env:Body>
</env:Envelope>
XML
driver.wiredump_dev = STDOUT

ele = SOAP::SOAPString.new(‘[email protected]’)
ele.elename = XSD::QName.new(nil, ‘account’)
ele.extraattr[XSD::QName.new(nil, ‘by’)] = ‘name’

!!! a wrapper element is needed for document service.

req = SOAP::SOAPElement.new(XSD::QName.new(ns, ‘GetAccountRequest’))
req.add(ele)

get_account = driver.get_account(req)
map = {}
get_account.account.a.each do |value|
map[value.xmlattr_n] = value
end
p map # => {“key1”=>“value1”, “key2”=>“value2”, “key3”=>“value3”}

Now you want to write WSDL, don’t you? :slight_smile:

The app I am using is Zimbra, in case anyone has any experience or
advice for use with Soap4r.

Please let me know if you succeeded to use it. Users must be interested
in it.

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)

iQEVAwUBRUvx4B9L2jg5EEGlAQLAQAgAp5dEsugVXp1jPPsOJJ10fanLzbK+oFY2
4qQ8tpziNHIIMs5oZVxsv+/hoY+64jrqMoTgmpidZ3Pdo84YS3pwMtSCgda7r9UQ
r0sw+JmjUMqfzgdN2tK7A8+nidKGpXYV4PDnWJPfk4iav3Dhk5xtFV8v/oM3WpnQ
tqGUV0BcSJ5fmXz+E6rvsG1LPPMQcnGWQI6SSpArYuR0ATdL7ff2HfOBEHAkaqFM
3H401RjnyTrYlHjO+uJUANNgzdVaF/Tl//z0omSSBa3z/uqx5EE6mcmjZSJ0QKTr
6b/xHBeqzpG09XrKgW9VDUjJRkUx9wxewQsrK+6b1RnFU/W0/Owhlg==
=SbKf
-----END PGP SIGNATURE-----