Delphi,SOAP和用CDATA包装值

10 浏览
0 Comments

Delphi,SOAP和用CDATA包装值

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

现在,第三方告诉我们,我们传递的其中一个widestring值必须包裹在CData节中。

在Delphi 2007中,有没有一种方法可以控制特定属性在soaprequest中如何转换为xml,以便我们可以控制值是否被编码,以及值是否应该被包裹在cdata节中?

或者我们通过编码值或不编码值,并自行包裹值来控制这个过程?

谢谢,

-Vegar

0
0 Comments

Delphi中使用SOAP进行数据传输时,有时候需要在XML中包裹一些特殊字符的值。然而,直接将这些值作为字符串字面量插入XML中是不可取的,因为这样做可能会导致数据在未来的某个时候出现错误,特别是当数据本身包含需要转义的字符时。

为了解决这个问题,可以使用Delphi中的TDomCDATASection类。这个类是对XML DOM中的CDATASection的Delphi封装。通过使用TDomCDATASection类,可以将需要包裹的值存储为CDATA。

在使用TDomCDATASection类存储base64编码数据的示例可以在这里找到。

需要注意的是,为了进行正确的base64编码,需要协商字符串数据的字符集和原始字节格式(大端、小端、8位、16位等)。

另外,在SOAP响应中插入CDATA需要进行一些底层操作。有几种方法可以尝试:

1. 创建TOPToSoapDomConvert的子类

2. 重写TOPToSoapDomConvert.ConvertNativeDataToSoap或TOPToSoapDomConvert.MakeResponse方法

3. 将TOPToSoapDomConvert的实例赋值给THTTPRIO的Converter属性

或者可以尝试以下方法:

1. 创建TTypeTranslator的子类

2. 重写TTypeTranslator.CastNativeToSoap方法

3. 将TTypeTranslator的实例赋值给TypeTrans单元中的TypeTranslator变量

需要注意的是,这种方法比较困难,如果不需要的话最好不要这样做。

在使用wsdl导入接口并调用接口方法时,会传递生成的类的实例,而不会直接操作XML。从代码中可以看出,THTTPRio类会将方法调用和参数转换为XML并发送到服务器。由于我们不直接操作XML,所以无法看到应该如何使用TDomCDATASection类。

关于为什么要使用CDATA存储已经进行了base64编码的数据,有人提出了不同的观点。其中一种观点认为,如果字符串已经进行了base64编码,那么它不包含任何需要在XML中转义的XML字符,因此没有必要将其放入CDATA节中,而可以直接使用普通的文本节点。

总结起来,如果字符串已经进行了base64编码,那么可以直接使用普通的文本节点。如果字符串包含了需要转义的字符,可以使用Delphi中的TDomCDATASection类将其包裹起来。

0
0 Comments

问题的原因是供应商可能不理解Cdata的含义,他们可能认为将值放在Cdata节中更容易阅读和编写,但实际上XML解析器并不真正关心这一点。如果是这种情况,可以忽略供应商的指示,继续使用XML库创建普通文本节点,库的序列化程序会自动转义需要转义的字符。

解决方法是告诉供应商他们的系统有问题,如果它不能正确处理Cdata,那么还会有其他什么地方出错呢?除非供应商非常负责,否则你可能没有办法解决这个问题。对于Delphi SOAP,你无法控制XML的生成方式,因为你无法提供IDomDocument,也无法在其上调用createCdataSection来控制程序发送的请求的结构。

文章整理如下:

Cdata、Delphi和在Cdata中包装值的解决方法

Cdata节只是不需要常规XML转义的字符值。例如,您可以使用文本<而不是使用转义的&lt;。这就是Cdata的全部意思。如果供应商说值必须在Cdata节中,那么可能有两种可能性:

1. 供应商不理解Cdata的含义。在测试期间,他们可能总是将自己的内容放在Cdata节中,因为这样更容易阅读和编写,但他们可能没有意识到XML解析器实际上并不关心这一点。

2. 供应商使用的XML解析器不符合规范,因此对待Cdata节中的值与裸文本节不同。

如果是第一种情况,那么可以忽略供应商的指示,继续使用XML库创建普通文本节点,库的序列化程序将自动转义需要转义的字符。

但如果是第二种情况,那么应该告诉供应商他们的系统有问题。如果系统不能正确处理Cdata,那还可能有其他什么地方出错呢?除非供应商非常负责,否则你可能无法解决这个问题。对于Delphi SOAP,你无法控制XML的生成方式,因为你无法提供IDomDocument,也无法在其上调用createCdataSection来控制程序发送的请求的结构。

供应商仍然要求使用Cdata,但我看不出实际系统是否真的在乎,所以我会选择第一种选项...

0