开发者

Delphi, soap and wrapping values in cdata

We have imported a w开发者_StackOverflowsdl 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


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜