【问题标题】:Delphi, soap and wrapping values in cdataDelphi、soap 和 cdata 中的包装值
【发布时间】:2011-04-15 18:24:57
【问题描述】:

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

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

在 Delphi 2007 中,有没有一种方法可以控制给定属性如何在 soaprequest 中转换为 xml,这样我们就可以控制值是否被编码,以及值是否应该包装在 cdata-section 中还是不行?

或者我们是否通过编码或不编码来控制这一点,并将值包装到我们自己?

问候, - 素食

【问题讨论】:

    标签: delphi soap encode cdata


    【解决方案1】:

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

    1. 供应商不理解 Cdata 的含义。在测试期间,他们可能总是将自己的东西放在 Cdata 部分,因为人类更容易读写,但没有意识到 XML 解析器并不真正关心。
    2. 供应商使用的 XML 解析器不符合规范,因此处理来自 Cdata 部分的值不同于纯文本部分。

    如果是前者,则忽略供应商的说明,继续使用您的 XML 库创建普通文本节点。库的序列化器会自动转义需要转义的字符。

    但如果是后者,那么你应该告诉供应商它的系统坏了。如果它不能正确处理 Cdata,它还有什么问题?除非您的供应商反应迅速,否则我认为您不走运。使用 Delphi SOAP,您无法控制 XML 的生成方式。您没有提供IDomDocument,因此您无法调用createCdataSection 来控制您的程序发送的请求的结构。

    【讨论】:

    • 供应商仍然需要 cdata,但我看不到实际的系统关心,所以我会选择选项 1....
    【解决方案2】:

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

    您需要根据需要使用 TDomCDATASection 类。它是 XML DOM (DOMCDATASection) 的 CDATASection 周围的 Delphi 包装器。

    here 是一个关于如何使用它来存储 base64 编码数据的示例。

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

    编辑:

    将 CDATA 插入到您的 SOAP 响应中需要您深入了解。

    您可以尝试以下几种方法:

    1. 创建TOPToSoapDomConvert 的后代
    2. 在后代中覆盖 TSOAPDomConv.ConvertNativeDataToSoapTOPToSoapDomConvert.MakeResponse 方法
    3. TOPToSoapDomConvert 后代的实例分配给 THTTPRIO 实例的 Converter 属性

    另一种方式可能是这个:

    1. 创建TTypeTranslator 的后代
    2. 覆盖TTypeTranslator.CastNativeToSoap
    3. TTypeTranslator 后代的实例分配给TypeTrans 单元中的TypeTranslator 变量

    这很难,如果不需要,不要那样做。

    --杰罗恩

    【讨论】:

    • 我们已经导入了一个wsdl,并调用给定的接口方法,传递生成类的实例。我们从不接触我们自己的 xml。我猜想 THTTPRio 类如何将带有参数的方法调用转换为 xml 并将其发送到服务器。由于我们从不接触 xml,我看不出我们应该在哪里使用 TDomCDATASection-class...
    • 到底为什么要使用 Cdata 部分来存储已经经过 base-64 编码的内容? Base64 不使用任何需要在 XML 中转义的字符。
    • @Vegar:我以为你无论如何都会去金属上插入 CDATA。
    • @Rob:你必须非常小心字符串和 CDATA;只要您的字符串包含“]]>”,它将结束 CDATA。这就是为什么很多人在 CDATA 中编码 base64(他们可以在任何 XML 元素中这样做)。另一种选择是将“]]>”包装到多个 CDATA 标记中:stackoverflow.com/questions/223652/…
    • 我的意思是,如果您的字符串已经 base-64-encoded,那么您已经知道它不包含任何 XML 字符.它不包含尖括号、和号或方括号,因此绝对没有理由将文本放在 cdata 部分中。只需使用一个普通的文本节点。
    猜你喜欢
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2018-07-03
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多