Reputation: 53
I have an XML file with:
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<doc:Request>
... some XML text as flat text or like XML ...
</doc:Request>
</soapenv:Body>
</soapenv:Envelope>
I need to save text between <doc:Request>
</doc:Request>
to new a message and save it as an XML file.
Upvotes: 1
Views: 2102
Reputation: 840
The xpath and distinguished field will work. But isn't the easy way is define the xml content struct with soapenv namespace as an envelop schema, then let the xmldisassmbler do the rest of thing?
Upvotes: 1
Reputation: 2435
Create a distinguished field in the incoming message schema (Make sure you are taking a copy of the schema for best practices) which points to doc:Request (I'm assuming that the doc namespace is registered in the message). Then create a Message Assignment Shape and simply instantiate a new message of the required type (you will need a new schema which describes doc:Request of course)
newMessageType.body = incomingMessage.Request;
You could do it by xpath if you really must but please know that for each time you execute an xpath query, the entire message is loading into memory. This can result in a massive overhead if your messages are large or you have a large number of xpath queries. In addition, your xpath can be difficult to read if your message is complex. Where a distinguished field will always be easy to read and if you update your schema, you don't need to alter the orchestration. I'd strongly recommend against using xpath!
Note If the sole purpose of your task here is to get that bit out of the message and save it as an XML file as you state here, you don't even need an orchestration. You can add a map to the receive port which transforms to the new message type and have a send port subscribe to the output doc:Request message which simple saves via a file adapter.
Upvotes: 2
Reputation: 21641
In an Orchestration, use the xpath()
in a Message Assignment shape:
msgExtracted = xpath(msgSoap, "/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='Request']");
In a custom pipeline component, load the pInMsg.BodyPart.GetOriginalDataStream()
into an XmlReader, and then ReadToFollowing("Request", "namespace_for_doc_here");
node and then use reader.ReadSubtree()
to get it and return it as the message.
Finally, since there's a good possibility you're using a WCF based adapter anyway, you may be able to specify the Body XPath
of the message in the adapter settings - or just tell the adapter to include the SOAP body and not the envelope.
Upvotes: 3