How to sort XML file using Ruby nokogiri - ruby-on-rails

I want to sort this XML such that same type of demographics show first like all staty_type="REACH" appear on top, then all clicks and so on.
Here is an example object:
<?xml version="1.0"?>
<properties date="2020-06-23">
<property>
<order start="2020-06-23" end="2020-06-23">52658</order>
<demographics demographic="Age" stat_type="REACH">
<value category="18-24">36</value>
<value category="25-34">149</value>
</demographics>
<demographics demographic="Age" stat_type="CLICK">
<value category="18-24">6</value>
<value category="25-34">37</value>
</demographics>
<demographics demographic="Gender" stat_type="REACH">
<value category="female">402</value>
<value category="male">188</value>
</demographics>
<demographics demographic="Gender" stat_type="CLICK">
<value category="female">107</value>
<value category="male">44</value>
</demographics>
</property>
</properties>
I'm able to iterate XML. However, unable to perform sorting.
#doc = Nokogiri::XML(File.open("public/test.xml"))
builder = #doc.xpath("//property")
builder.search('./demographics').sort_by{|t| puts t['stat_type']}.each do |table|
puts table.to_s
end
I need the final XML in this form.
<?xml version="1.0"?>
<properties date="2020-06-23">
<property>
<order start="2020-06-23" end="2020-06-23">PBNI152658</order>
<demographics demographic="Age" stat_type="REACH">
<value category="18-24">36</value>
<value category="25-34">149</value>
</demographics>
<demographics demographic="Gender" stat_type="REACH">
<value category="female">402</value>
<value category="male">188</value>
</demographics>
<demographics demographic="Age" stat_type="CLICK">
<value category="18-24">6</value>
<value category="25-34">37</value>
</demographics>
<demographics demographic="Gender" stat_type="CLICK">
<value category="female">107</value>
<value category="male">44</value>
</demographics>
</property>
</properties>

When you do things like builder.search('./demographics') you just create a new nodeset with some nodes filtered from the initial XML document. Even if you sort this new nodeset you don't affect the initial document itself.
To sort the nodes of the initial document you have to rebuild the children of the node in question (<property> in your case). And here comes a tiny additional challenge - there are more nodes parsed by Nokogiri to take into account, not only the ones to sort:
pry(main)> #doc.at_xpath("//property").children.map(&:node_name)
=> ["text", "order", "text", "demographics", "text", "demographics", "text", "demographics", "text", "demographics", "text"]
So, what we have to do is to sort demographics nodes only and keep everything else untouched. One of the ways to do this is:
property_node = #doc.at_xpath("//property")
nodes_to_sort = property_node.children.dup
# My sorting logic is dumb here, apply your own as necessary
sorted_demographics = nodes_to_sort.select { |n| n.node_name == "demographics" }.sort_by { |n| n.attr("stat_type") }.reverse
# Create an empty nodeset. There should be a more idiomatic and readable way but this trick works too
new_nodeset = nodes_to_sort - nodes_to_sort
nodes_to_sort.each do |n|
case n.node_name
when "demographics"
new_nodeset << sorted_demographics.shift
else
new_nodeset << n
end
end
property_node.children = new_nodeset
And voila! - we are sorted now:
pry(main)> puts #doc
<?xml version="1.0"?>
<properties date="2020-06-23">
<property>
<order start="2020-06-23" end="2020-06-23">52658</order>
<demographics demographic="Gender" stat_type="REACH">
<value category="female">402</value>
<value category="male">188</value>
</demographics>
<demographics demographic="Age" stat_type="REACH">
<value category="18-24">36</value>
<value category="25-34">149</value>
</demographics>
<demographics demographic="Gender" stat_type="CLICK">
<value category="female">107</value>
<value category="male">44</value>
</demographics>
<demographics demographic="Age" stat_type="CLICK">
<value category="18-24">6</value>
<value category="25-34">37</value>
</demographics>
</property>
</properties>
NB. Take the solution above with a grain of salt - I don't know nokogiri's XML building capabilities well, so chances are there are some ways to achieve the same result with less code/in a more idiomatic way.

Related

Make a request application/x-www-form-urlencoded using wso2 esb

I trying to retrive a token OAuth2. But I don't khnow how I can make a x-www-form-urlencoded request using wso2esb.
This is a snippet of my code:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="test-oauth_v1" xmlns="http://ws.apache.org/ns/synapse">
<in>
<property name="RESPONSE" scope="default" value="true"/>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<header action="remove" name="To"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="basicAuth" scope="default" type="STRING" value="Z3FZVFhUQnhkQlVGNDloblxxzedtSGRBQ1kySWpmSmNvZXdh"/>
<script language="js"><![CDATA[
var body = {};
body.grant_type = 'password';
body.username = 'xxxx';
body.password = 'xxxxxxx';
mc.setPayloadJSON(body);
]]></script>
<property name="messageType" scope="default" type="STRING" value="application/x-www-form-urlencoded"/>
<header
expression="fn:concat('Basic ', get-property('basicAuth'))"
name="Authorization" scope="transport" xmlns:ns="http://org.apache.synapse/xsd"/>
<call>
<endpoint key="server_token_oauth"/>
</call>
<send />
</in>
</sequence>
Would you have any propositions ?
Best regards
You can refer this example [1]. Scope of the messageType should be axis2.
<property name="messageType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING"/>
<property name="DISABLE_CHUNKING" value="true" scope="axis2" type="STRING"/>

How to convert an array of hashes into XML in Rails?

I have an array of database objects, #configs, that I want to convert to the XML format but the output is not the expected. Every entry gets enclosed in a <map> tag instead of a <entry> tag, I only wanted <tag> to be the XML root. How do I build the XML with the <tag> root and put all the entries in a <entry> tag?
Thank you in advance for your help and time!
Here is my code:
entries = Array.new
entry = Hash.new
conf = Hash.new
#configs.each do |config|
entry.store('string', config.key)
conf.store('value', config.value)
conf.store('comment', config.comment)
entry.store('com.mirth.connect.util.ConfigurationProperty', conf)
entries << entry
end
pp entries.to_xml(:root => 'map', :indent => 0, :skip_types => true)
And the result is:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<map>
<map>
<string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>PNB_ALERTLOG_RECEIVER</value>
<comment>Canal que irá receber tudo o que for logged com Warning e Error</comment>
</com.mirth.connect.util.ConfigurationProperty>
</map>
<map>
<string>PNB_CFG_FILE_ACCESS_CONTROL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/pnbAccessControl.json</value>
<comment>Este ficheiro permite configurar Autenticação e Controlo de Acessos.</comment>
</com.mirth.connect.util.ConfigurationProperty>
</map>
<map>
<string>PNB_CFG_FILE_CONNECTION_POOLS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/pnbConnectionPools.json</value>
<comment>Configuração de Oracle Universal Connection Pools usadas pelo PNB (PEM, RCU2)</comment>
</com.mirth.connect.util.ConfigurationProperty>
</map>
<map>
<string>PNB_CFG_FILE_CSP_MC_EXCLUSIONS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/medCronExclusions/mcExclCurrentRevision.json</value>
<comment>N/A</comment>
</com.mirth.connect.util.ConfigurationProperty>
</map>
<map>
<string>PNB_CFG_FILE_FACILITIES_ALIAS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/snsFacilitiesAlias.json</value>
<comment>Mapa de alias do codigo das instituicoes do SNS.</comment>
</com.mirth.connect.util.ConfigurationProperty>
</map>
</map>
What I wanted:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<map>
<entry>
<string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>PNB_ALERTLOG_RECEIVER</value>
<comment>Canal que irá receber tudo o que for logged com Warning e Error</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
<entry>
<string>PNB_CFG_FILE_ACCESS_CONTROL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/pnbAccessControl.json</value>
<comment>Este ficheiro permite configurar Autenticação e Controlo de Acessos.</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
<entry>
<string>PNB_CFG_FILE_CONNECTION_POOLS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/pnbConnectionPools.json</value>
<comment>Configuração de Oracle Universal Connection Pools usadas pelo PNB (PEM, RCU2)</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
<entry>
<string>PNB_CFG_FILE_CSP_MC_EXCLUSIONS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/medCronExclusions/mcExclCurrentRevision.json</value>
<comment>N/A</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
<entry>
<string>PNB_CFG_FILE_FACILITIES_ALIAS</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/snsFacilitiesAlias.json</value>
<comment>entrya de alias do codigo das instituicoes do SNS.</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
</map>
try this:
pp entries.to_xml(:root => 'map', :children => 'entry', :indent => 0, :skip_types => true)
source: http://apidock.com/rails/Array/to_xml
Suppose entry is the following hash:
entry = {
a: “hello”,
b: “goodbye”,
}
If you write:
entries = []
entries << entry
p entries
then the output is:
[{:a => “hello”, {:b => “goodbye”}]
So if you then write:
p entries.to_xml
how do you suppose the word “entry” will ever appear in the output? That's sort of like expecting the output of:
x = 10
y = 20
puts x+y
to include the letters "x" and "y" somewhere.
According to the to_xml() docs for arrays:
Returns a string ... by invoking to_xml on each element.
The options hash is passed downwards.
http://apidock.com/rails/Array/to_xml
The fact that the options hash is passed downwards means that when you specify {root: map} for the to_xml() call on the array, then <map> will become the root of the xml, and when to_xml() is called on each array element the method will be called with the option {root: “map”}, which will cause each array element to be wrapped in a <map> tag. For instance:
puts [{a: 10, b: 20}, {a: 100, b: 200}].to_xml({root: "map"})
--output:--
<?xml version="1.0" encoding="UTF-8"?>
<map type="array">
<map>
<a type="integer">10</a>
<b type="integer">20</b>
</map>
<map>
<a type="integer">100</a>
<b type="integer">200</b>
</map>
</map>
The nested <map> tags are a side effect of a feature built into the to_xml() method: if you specify a plural name for the :root option when calling to_xml() on an array, e.g. “maps”, then when rails turns around and calls to_xml() on each element of the array, rails will specify the singular “map” for the :root option. That makes some sense because if you call to_xml() on an array and you specify the :root option to be “maps” then naturally each array element would probably be a "map". Of course, that isn’t what you want.
Luckily, as mr_sudaca pointed out, there is this:
By default name of the node for the children of root is
root.singularize. You can change it with the :children option.
http://apidock.com/rails/Array/to_xml
As a result, this code:
require 'ostruct'
configs = [
OpenStruct.new(
key: "PNB_ALERTLOG_RECEIVER_CHANNEL",
value: "PNB_ALERTLOG_RECEIVER",
comment: "Canal que...",
),
OpenStruct.new(
key: "PNB_CFG_FILE_ACCESS_CONTROL",
value: "resources/configPnbDev/pnbAccessControl.json",
comment: "Este ficheiro...",
)
]
entries = []
configs.each do |config|
entry = {}
conf = {}
entry.store('string', config.key)
conf.store('value', config.value)
conf.store('comment', config.comment)
entry.store('com.mirth.connect.util.ConfigurationProperty', conf)
entries << entry
end
p entries
puts entries.to_xml(:root => 'map', children: "entry", :skip_types => true)
produces the output:
<?xml version="1.0" encoding="UTF-8"?>
<map>
<entry>
<string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>PNB_ALERTLOG_RECEIVER</value>
<comment>Canal que...</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
<entry>
<string>PNB_CFG_FILE_ACCESS_CONTROL</string>
<com.mirth.connect.util.ConfigurationProperty>
<value>resources/configPnbDev/pnbAccessControl.json</value>
<comment>Este ficheiro...</comment>
</com.mirth.connect.util.ConfigurationProperty>
</entry>
</map>
It looks to me like you also have some problems with your entry and conf hashes as every element in the entries array will refer to the same entry and conf hash, and because your loop keeps changing those hashes, each entry in the array will refer to a hash that contains the last key/values set in the loop.

How to parse an XML file with metadata key names?

I've recently started using Nokogiri as a solution to parsing data into a RAILS 3 application. The problem I'm having is that I don't fully understand how to do it as the XML I am parsing appears to be 'non-standard'. Take a look at the snippet below:
<?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<!--
<dataset
xmlns="http://.com/schemas/xmldata/1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://.com/schemas/xmldata/1/ xmldata.xsd"
>
-->
<metadata>
<item name="Problem ID" type="xs:string" length="32"/>
<item name="Account Title" type="xs:string" length="162"/>
<item name="Account Name" type="xs:string" length="162"/>
<item name="Reassignment" type="xs:int" precision="1"/>
<item name="Initial Severity" type="xs:int" precision="1"/>
<item name="Resolution Desc" type="xs:string" length="510"/>
<item name="Resolver Name" type="xs:string" length="82"/>
<item name="Problem Code" type="xs:string" length="32"/>
<item name="Status" type="xs:string" length="32"/>
</metadata>
<data>
<row>
<value>AP-06684768 </value>
<value>ESA</value>
<value>1</value>
<value>8</value>
<value>8</value>
<value xs:nil="true" />
<value xs:nil="true" />
<value>ADDITION TO EXISTING FIREWALL</value>
<value></value>
<value>ESA BRIDGE </value>
<value>CLOSED </value>
<value>CLOSED </value>
</row>
<row>
<value>AP-06720564 </value>
<value>ESA</value>
<value>2011-01-19T12:02:47</value>
<value>2011-01-19T12:02:49</value>
<value>0</value>
<value>776</value>
<value>SCP UESCADADEV -> UESCADAPW/BW</value>
<value>NETAU_NETMGTS </value>
<value>N/A</value>
<value>ESA BRIDGE </value>
<value>CLOSED </value>
<value>CLOSED </value>
</row>
</data>
</dataset>
Instead of having named nodes and attributes it seems to be a 'metadata' section and then rows, much like a table really. How would I parse all this data?
require 'rubygems'
require 'nokogiri'
require 'pp'
doc = Nokogiri::XML(DATA)
column_names = doc.css('dataset > metadata > item').map {|a| a['name']}
result = doc.css('dataset > data > row').map do |row|
values = row.css('value').map { |value| value[:nil] == 'true' ? nil : value.content }
Hash[column_names.zip(values)]
end
pp result
results in
[{"Problem Code"=>"ADDITION TO EXISTING FIREWALL",
"Resolution Desc"=>nil,
"Reassignment"=>"8",
"Resolver Name"=>nil,
"Status"=>"",
"Problem ID"=>"AP-06684768 ",
"Account Name"=>"1",
"Initial Severity"=>"8",
"Account Title"=>"ESA"},
{"Problem Code"=>"NETAU_NETMGTS ",
"Resolution Desc"=>"776",
"Reassignment"=>"2011-01-19T12:02:49",
"Resolver Name"=>"SCP UESCADADEV -> UESCADAPW/BW",
"Status"=>"N/A",
"Problem ID"=>"AP-06720564 ",
"Account Name"=>"2011-01-19T12:02:47",
"Initial Severity"=>"0",
"Account Title"=>"ESA"}]
Here's working code that I hacked out and tested:
require 'rubygems'
require 'nokogiri'
class Item
attr_accessor :name
def initialize(name)
#name = name
end
end
file = File.open("data.xml")
document = Nokogiri::XML(file)
file.close
metadata = document.root.children[3]
items = metadata.children.reject{|child| child.attribute('name').nil?}.map do |child|
Item.new(child.attribute('name').value)
end
puts "#{items.size} items"
puts items.inspect
Results:
[~/stackoverflow/graphML] ruby parse.rb
9 items
[#<Item:0x007fc01c0fbd90 #id="Problem ID">, #<Item:0x007fc01c0fbca0 #id="Account Title">, #<Item:0x007fc01c0fbc28 #id="Account Name">, #<Item:0x007fc01c0fbbb0 #id="Reassignment">, #<Item:0x007fc01c0fbb38 #id="Initial Severity">, #<Item:0x007fc01c0fbac0 #id="Resolution Desc">, #<Item:0x007fc01c0fba48 #id="Resolver Name">, #<Item:0x007fc01c0fb9d0 #id="Problem Code">, #<Item:0x007fc01c0fb868 #id="Status">]
Here's the full project on GitHub: https://github.com/endymion/GraphML-parsing-exercise/tree/metadata-key-names
(It's a branch of a GraphML parsing exercise that I hacked out earlier tonight for somebody else on Stack Overflow.)

How can I use j_spring_security_check

I am using spring 3 + struts 2 + hibernate 3, following is my configuration:
app-security:
<beans:import resource="datasource.xml"/>
<http auto-config='true'>
<intercept-url pattern="/CMS/login*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page='/CMS/login' default-target-url="/j_spring_security_check"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService">
<!-- <password-encoder hash="md5"/>-->
</authentication-provider>
</authentication-manager>
</beans:beans>
datasource.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<bean id="userDetailsService"
class="mo.cam.service.impl.UserDetailsServiceImpl">
<property name="dataSource" ref="dataSource"/>
<property name="enableAuthorities" value="true"/>
<property name="usersByUsernameQuery">
<value>SELECT LOGIN, PASSWORD,
1 FROM USER_INFO WHERE LOGIN = ?
</value>
</property>
<property name="groupAuthoritiesByUsernameQuery">
<value>SELECT G.GROUP_ID, G.GROUP_NAME, P.NAME
FROM USER_INFO U
JOIN USER_GROUP UG on U.USER_INFO_ID = UG.USER_INFO_ID
JOIN GROUP G ON UG.GROUP_ID = G.GROUP_ID
JOIN GROUP_PERMISSION GP ON G.GROUP_ID = GP.GROUP_ID
JOIN PERMISSION P ON GP.PERMISSION_ID = P.PERMISSION_ID
WHERE U.LOGIN = ?
</value>
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.microsoft.sqlserver.jdbc.SQLServerDriver">
</property>
<property name="url"
value="***">
</property>
<property name="username" value=""></property>
<property name="password" value=""></property>
</bean>
</beans>
and then setup my login page, but system just show me that :
no action is defined for /cms/j_acegi_security_check
and I tried to set a break point at :mo.cam.service.impl.UserDetailsServiceImpl, but it won't break!
why ?
You should define the login's target url to /j_spring_security_check (as you defined in app:security) instead of /j_acegi_security_check

WSDL list of complexType HOWTO- define, return from a service?

How do you define a list of complex type items in WSDL?
I have a rather simple WSDL with 2 complex types
<xsd:complexType name="itemProperty">
<xsd:all>
<xsd:element name="name" type="xsd:string" />
<xsd:element name="value" type="xsd:string" />
<xsd:element name="type" type="xsd:string" />
</xsd:all>
</xsd:complexType>
Then i'm trying to make a list of this complexType like this:
<xsd:complexType name="itemPropertyList">
<xsd:complexContent>
<xsd:restriction base="SOAP-ENC:Array">
<xsd:sequence>
<xsd:element name="item" type="tns:itemProperty"
maxOccurs="unbounded" minOccurs="0" />
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
I intend to use this list
<message name="getListRequest"></message>
<message name="getListResponse">
<part name="return" type="tns:itemPropertyList" />
</message>
<operation name="getList">
<documentation>Returns an array.</documentation>
<input message="tns:getListRequest" />
<output message="tns:getListResponse" />
</operation>
Instead of a list of elements of type itemProperty, I get this reply, no matter what variations i've tryed (including replacing the base item with the explicit string elements)
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getListResponse>
<return SOAP-ENC:arrayType="ns2:Map[1]" xsi:type="SOAP-ENC:Array">
<item xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">name</key>
<value xsi:type="xsd:string">name_4c3b38b0b77ae</value>
</item>
<item>
<key xsi:type="xsd:string">value</key>
<value xsi:type="xsd:string">name_4c3b38b0b77ee</value>
</item>
<item>
<key xsi:type="xsd:string">type</key>
<value xsi:type="xsd:string">name_4c3b38b0b782b</value>
</item>
</item>
</return>
</ns1:getListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Any ideas? What is this ns2:Map thing? It's been haunting me for over a week!
Solved.
I used the AXIS model for delivering lists. This involved extending the namespaces attributes to include some extra encodings. I don't know which did the trick, I just added as many as possible while resolving conflicts with the help of eclipse's WSDL editor.
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="urn:mynamespace"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:mynamespace"
xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:ax21="http://example.org/xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
Also I added 2 extra attributes to declare qualified-form attributes and elements within the schema
<xsd:schema targetNamespace="urn:mynamespace" attributeFormDefault="qualified" elementFormDefault="qualified">
...
</xsd:schema>
Instead of relying on the ComplexType declaration to make a "nillable" unbounded sequence of a complex type within my schema, I switched to declare an element like this:
<xsd:element name="getListResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="tns:itemProperty" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Then, when defining the message part for the operation I used
<message name="getListResponse">
<part name="parameters" element="tns:getListResponse" />
</message>
instead of
<message name="getListResponse">
<part name="return" type="tns:itemPropertyList" />
</message>
This resulted in a correct enveloper returned:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:mynamespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getListResponse>
<parameters xsi:type="ns1:getListResponse">
<return xsi:type="ns1:itemProperty">
<name xsi:type="xsd:string">name4c4417b644a8e</name>
<value xsi:type="xsd:string">value4c4417b644aaa</value>
<type xsi:type="xsd:string">type4c4417b644ae8</type>
</return>
<return xsi:type="ns1:itemProperty">
<name xsi:type="xsd:string">name4c4417b644b26</name>
<value xsi:type="xsd:string">value4c4417b644b64</value>
<type xsi:type="xsd:string">type4c4417b644ba1</type>
</return>
<return xsi:type="ns1:itemProperty">
<name xsi:type="xsd:string">name4c4417b644bdf</name>
<value xsi:type="xsd:string">value4c4417b644c1c</value>
<type xsi:type="xsd:string">type4c4417b644c59</type>
</return>
</parameters>
</ns1:getListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Resources