WSDL for service accepting different messages in a single operation - web-services

I'd like to have a document\literal web-service accepting different kind of input in soap:body. Smth like
<soap:body>
<A xmlns="http://tempuri/A">
</A>
</soap:body>
as well as
<soap:body>
<B xmlns="http://tempuri/B">
</B>
</soap:body>
in the same wsdl:operation.
I tried describing and elements in inline schema block inside WSDL, but for a document\literal-style i need to specify an element for a wsdl:message part. But I don't want to wrap the request (<A> or <B>) into another container element.
Is this possible?

No it is not possible. The only way can get it working is to wrap those A and B elements with the other element for e.g. C. Then you need to specify that C element in your WSDL message.
Why this not possible because you have two different elements pointing at two different namespaces and the message only allows one element from one namespace.

Related

BizTalk mapping: Getting a value from soapenv:Header

I'm trying to map a message from the following format via xslt:
<soapenv:Envelope xmlns:soapenv="..." ns...>
<soapenv:Header>
<ns:myHeader>
<ns1:myData>VALUE_I_WANT</ns1:myData>
</ns:myHeader>
</soapenv:Header>
<soapenv:Body>
<ns2:otherData>
...
</ns2:otherData>
</soapenv:Body>
</soapenv:Envelope>
Currently my mapping handles all of the fields in the soapenv:Body tag, but for one of my mapped nodes I need the value in soapenv:Header > ns:myHeader > ns1:myData.
Is it possible to get a value from the soap header in XSLT and what kind of xpath would I need to achieve this?
Assuming you use the WCF-BasicHttp adapter, you could use xslt like you wanted, but only if you specified Envelope -- entire <soap:Envelope> as data selection for the SOAP Body element. If you don't specify it, your header will be removed from the message body and xpath statements on the header will be impossible.
Your other option is getting the value from the context property InboundHeaders with namespace http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties. The adapter puts the SOAP header values into that InboundHeaders context property by default. If you need the context value in a mapping, without an orchestration, try looking into the community made Context Accessor Functoid.
Doing your own property promotion on header values, like you asked for in the comments, is also possible, but not in xslt. Only if you add an XML Disassembler Pipeline Component, then make a schema of the entire soap message, then set promotions on the schema and finally; specify the schema in the Document schemas part of the Pipeline Component. I wouldn't suggest using this approach, as it requires you to deploy a soap schema which will be duplicate with the default BizTalk soap schema.

TrimDuplicates element of Microsoft.Search.Query Webservice causes a FormatException

I'm trying to search through a site collection and find all sites that contain a particular file. TrimDuplicates is supposed to be the right way to do that. I'm calling QueryEx of the WebService object with the following XML as the string argument.
<QueryPacket xmlns='urn:Microsoft.Search.Query'>
<Query>
<TrimDuplicates includeid="false">False</TrimDuplicates>
<SupportedFormats>
<Format revision='1'>urn:Microsoft.Search.Response.Document:Document</Format>
</SupportedFormats>
<Context>
<QueryText language='en-us' type='STRING'>
"filenameForQuery"
</QueryText>
</Context>
</Query>
</QueryPacket>
The response from search.asmx is a 500 error with System.FormatException as the only piece of useful information.
It's only the TrimDuplicates element that is triggering the formatexception. Fiddling the case of the two Falses hasn't had any effect so far.
The answer is actually blindingly obvious - remove the includeid attribute and make the content of TrimDuplicates lower case.
Just wanted to point out that includeid should actually be an integer value.
More here
But as you said, it's not necessary.

How do I reproduce Relax NG rules in C++ objects?

At the momemet I am working on part of my application where I need to parse Relax NG schema and reproduce rules within file in C++ objects. I start with example code so I can explain better.
<!-- property.element -->
<define name="property.element">
<element name="property">
<attribute name="type" />
<interleave>
<zeroOrMore>
<ref name="resource.class" />
</zeroOrMore>
<ref name="literal.class" />
</interleave>
</element>
</define>
I want to create object where I can store information like:
[define] name,
element name,
attribute names,
allowed child elements with associated rules (zero or more, one or more).
Then I want to display all possible elements in my GUI where I can add only valid (in terms of Relax NG schema) elements to tree-like structure. For example - I can add only resource.class or literal.class to my property.element, every other possible element is greyed in my GUI when I have selected property.element node in GUI. I use Qt, so I load schema into QDomDocument to get access to DOM tree.
Such mechanism has to be universal i.e. no matter how elements are named, or how its structure is. In my draft I created simple class where I placed several members like: defined_name, element_name, required_attributes, optional_attributes. Currently I am stuck because I do not have any idea how to represent rules in C++ class. If I had constant set of objects on which I work I would hard-code every object, but my objects set is very likely to change drastically over time. Does anyone have any idea?
Convert the RNG file to XSD using TRANG, then convert the XSD to c++ using CodeSynthesis either XSD or XSDe). There are a bunch of samples with XSDe, so there might be one demonstrating how to validate the xml input with the schema rules.
http://www.thaiopensource.com/relaxng/trang.html
http://www.codesynthesis.com/products/xsde/

How to get first element name of the SOAP Body using XSLT?

<soap:envelope>
<soap:body>
<ns:Hello>11</ns:Hello>
<ns1:hai>12</ns1:hai>
</soap:body>
</soap:envelope>
from above i need to get first element name from the body root tag i.e, need to get output as a 'Hello'. Please help me, thanks in advance.
Use:
local-name(/*/*/*[1])
It is recommended to avoid using the // XPath pseudo-operator whenever the structure of the XML document is statically known, because many XPath engines evaluate it inefficiently (by traversing a complete (sub)tree).
<xsl:value-of select="local-name(//soap:body/*[1])" />

Xerces: How to merge duplicate nodes?

My question is this:
If I have the following XML:
<root>
<alpha one="start">
<in>1</in>
</alpha>
</root>
and then I'll add the following path:
<root><alpha one="start"><out>2</out></alpha></root>
which results in
<root>
<alpha one="start">
<in>1</in>
</alpha>
</root>
<root>
<alpha one="start">
<out>2</out>
</alpha>
</root>
I want to be able to convert it into this:
<root>
<alpha one="start">
<in>1</in>
<out>2</out>
</alpha>
</root>
Besides implementing it myself (don't feel like reinventing the wheel today),
is there a specific way in Xerces (2.8,C++) to do it?
If so, at which point of the DOMDocuments life is the node merging done? at each insertion? at the writing of the document, explicitly on demand?
Thanks.
If you use xalan its possible to use an xpath to find the element and directly insert into the correc one.
The following code may be slow but returns all "root" elments with the attribute "one" set to "start".
selectNodes("//root[#one="start"]")
It is probably better to use the full path
selectNodes("/abc/def/.../root[#one="start"]")
or if you already have the parent element work relative
selectNodes("./root[#one="start"]")
I think to get the basic concepts xpath on wikipedia.
Isn't it just a one minute task if you know the names of the container tag where various different tags are present?
In your example, get a pointer to the alpha tag in all the XML documents and put the contents of all of them into a new document's alpha if they're not present there already.
This isn't as bad as reinventing the wheel. I'm not familiar with Xerces, but with libxml++, I would call this an easy task.