在cdata中使用Delphi,soap和包装值

时间:2010-09-22 14:11:21

标签: delphi soap encode cdata

我们从第三方导入了一个wsdl。这为我们提供了一组接口,包括调用方法,以及参数和返回值的类。

现在,第三方告诉我们,我们传递的宽字符串值之一必须包含在CData部分中。

在Delphi 2007中,有没有办法控制给定属性如何在soaprequest中转换为xml,以便我们可以控制值是否被编码,以及是否应该将值包装在cdata-section中不是吗?

或者我们是否通过对值进行编码来控制它,并将值包装为自己?

的问候, -Vegar

2 个答案:

答案 0 :(得分:2)

永远不要将XML作为字符串文字,因为这通常会在将来某处失败,尤其是当您的数据本身包含需要以某种方式转义的字符时。

您需要使用TDomCDATASection类来获得所需内容。它是围绕XML DOM CDATASectionDOMCDATASection)的Delphi包装器。

有关如何使用它来存储base64编码数据的示例是here

请注意,您需要协商字符串数据的字符集和原始字节格式(big-endian,little-endian,8-bit,16-bit等),以便进行正确的base64编码。

修改

将CDATA插入到您的SOAP响应中需要您使用金属。

有几种方法可以尝试:

  1. 创建TOPToSoapDomConvert
  2. 的后代
  3. 覆盖后代中的TSOAPDomConv.ConvertNativeDataToSoapTOPToSoapDomConvert.MakeResponse方法
  4. TOPToSoapDomConvert后代的实例分配到Converter实例的THTTPRIO属性
  5. 另一种方式可能就是这个:

    1. 创建TTypeTranslator
    2. 的后代
    3. 覆盖TTypeTranslator.CastNativeToSoap
    4. TTypeTranslator后代的实例分配到TypeTranslator单元中的TypeTrans变量
    5. 很难,如果你不需要那么就不要这样做。

      - 的Jeroen

答案 1 :(得分:2)

Cdata部分只是不需要通常的XML转义的字符值。例如,您可以使用文字<字符,而不是使用&lt;转义它。这就是所有的Cdata。如果供应商说值必须在Cdata部分,那么我看到两种可能性:

  1. 供应商不了解Cdata的含义。在测试期间,他们可能总是将自己的东西放在Cdata部分,因为人们更容易读写,但没有意识到XML解析器并不真正关心。
  2. 供应商使用的XML解析器不符合规范,因此处理来自与裸文本部分不同的Cdata部分的值。
  3. 如果是前者,则忽略供应商的说明并继续使用XML库创建普通文本节点。库的序列化程序将转义需要自动转义的字符。

    但如果是后者,那么你应该告诉供应商它的系统坏了。如果它无法正确处理Cdata,还有什么其他错误?除非你的供应商非常敏感,否则我认为你运气不好。使用Delphi SOAP,您无法控制XML的生成方式。您没有提供IDomDocument,因此您无法在其上调用createCdataSection来控制程序发送的请求的结构。