views:

69

answers:

2

Hi,

We have imported a wsdl from a thirdparty. This gives us a set of interfaces with methods to call, and classes for parameters and returnvalues.

Now, the thirdparty have told us that one of the widestring values that we pass has to be wrapped in a CData-section.

In Delphi 2007, is there a way of controlling how a given property is converted into xml in a soaprequest, so that we can control if the value gets encoded or not, and if the value should be wrapped in a cdata-section or not?

Or do we control this by either encode the value or not, and wrap the value our self?

regards, -Vegar

A: 

Never ever do XML as string literals, as that usually will fail somewhere in the future, especially when your data itself contains characters that need to be somehow escaped.

You need to use the TDomCDATASection class for what you want. It is the Delphi wrapper around the CDATASection of an XML DOM (DOMCDATASection).

An example on how to use it to store base64 encoded data is here.

Note that you need to negotiate the character set and raw byte format (big-endian, little-endian, 8-bit, 16-bit, etc) of your string data so you can do the proper base64 encoding.

Edit:

Inserting CDATA into your SOAP response needs you to go down to the metal.

There are a couple of ways you could try:

  1. Create a descendant of TOPToSoapDomConvert
  2. Override TSOAPDomConv.ConvertNativeDataToSoap or TOPToSoapDomConvert.MakeResponse methods in your descendant
  3. Assign an instance of your TOPToSoapDomConvert descendant to the Converter property of your THTTPRIO instance

Another way might be this one:

  1. Create a descendant of TTypeTranslator
  2. Override TTypeTranslator.CastNativeToSoap
  3. Assign an instance of your TTypeTranslator descendant to the TypeTranslator variable in the TypeTrans unit

It is hard, don't go that way if you do not need to.

--jeroen

Jeroen Pluimers
We have imported a wsdl, and call the interface methods given, passing instances of generated classes. We never touch the xml our self. I guess the THTTPRio class some how converts the method call with parameters into an xml and sends it to the server. Since we never touch the xml, I can't see where we should take the TDomCDATASection-class to use...
Vegar
Why in the world would you use a Cdata section to store stuff that's already base-64 encoded? Base64 doesn't use any characters that would need to be escaped in XML.
Rob Kennedy
@Vegar: I was presuming you were going down to the metal anyway to insert the CDATA.
Jeroen Pluimers
@Rob: you have to be really carefull with strings and CDATA; as soon as your string contains "]]>" it will end the CDATA. That's why a lot of people encode base64 in CDATA (which they could just do in any XML element). The other alternative is to wrap the "]]>" into multiple CDATA tags: http://stackoverflow.com/questions/223652/is-there-a-way-to-escape-a-cdata-end-token-in-xml
Jeroen Pluimers
My point is that if your string is *already* base-64-encoded, then you already know that it doesn't contain *any* XML characters. It doesn't contain angle brackets, ampersands, or square brackets, so there's absolutely no reason to put the text in a cdata section. Just use an ordinary text node.
Rob Kennedy
@Rob: I did get your point; I just tried to explain why a lot of people are using CDATA in a way it is not supposed to be used. Sorry for the bad explanation :-)
Jeroen Pluimers
A: 

Cdata sections are simply character values that don't need the usual XML escaping. For example, you can have a literal < character instead of escaping it with &lt;. That's all Cdata is. If the vendor said the value must be in a Cdata section, then I see two possibilities:

  1. The vendor doesn't understand what Cdata means. During testing, they probably always put their own stuff in Cdata sections because it's easier for humans to read and write, but don't realize that the XML parser doesn't really care.
  2. The XML parser that the vendor uses doesn't comply with the spec, and therefore treats values from Cdata sections different from bare text sections.

If it's the former, then ignore the vendor's instructions and continue creating ordinary text nodes with your XML library. The library's serializer will escape the characters that need escaping automatically.

But if it's the latter, then you should tell the vendor its system is broken. If it can't handle Cdata correctly, what else is it doing wrong? Unless your vendor is very responsive, I think you're out of luck. With Delphi SOAP, you're not in control of how the XML is generated. You don't provide an IDomDocument, so you don't get to call createCdataSection on it to control the structure of the request your program sends.

Rob Kennedy