2

I need to implement a SOAP Request as WebServiceCallout which includes CDATA tags in its request envelope. The marshaller class has been auto-generated and the request is working just fine except that strings which include XML surrounded by CDATA tags are encoded, which means that < becomes &lt; and > becomes &gt;

Example:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <env:Header>
    </env:Header>
    <env:Body>
        <SomeSOAPCall xmlns="some_namespace">
            <username>username</username>
            <userrole>userrole</userrole>
            <xml>&lt;![CDATA[&lt;Attribute Name="attributeName" Value="attributeValue" />]]&gt;</xml>
        </SomeSOAPCall>
    </env:Body>
</env:Envelope>

But it should be the following - which is valid according to W3C specification:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <env:Header>
    </env:Header>
    <env:Body>
        <SomeSOAPCall xmlns="some_namespace">
            <username>username</username>
            <userrole>userrole</userrole>
            <xml><![CDATA[<Attribute Name="attributeName" Value="attributeValue" />]]></xml>
        </SomeSOAPCall>
    </env:Body>
</env:Envelope>

I don't want to use XMLStreamWriter as a workaround. Is there a way to use embedded XML using a WebServiceCallout where CDATA tags are not encoded?

Thanks!

3
  • Are you able to share the WSDL in question? Oct 9, 2018 at 20:52
  • Sorry, unfortunately I can't share it. It is also quite huge so that I needed to edit it a bit before I could render the APEX classes. The respective attribute has the following type according to the APEX class: public String xml; private String[] xml_type_info = new String[]{'xml','some_namespace','string','0','1','false'};
    – epanzer
    Oct 10, 2018 at 8:22
  • With "edited" I mean that I used your explorer tool :)
    – epanzer
    Oct 10, 2018 at 8:24

1 Answer 1

1

Unfortunately I think your options are limited here. You are at the mercy of WebServiceCallout.invoke and how it serializes the classes into XML.

As you've found, the applicable parts of the generated class that control this are

public String xml;
private String[] xml_type_info = new String[]{'xml','some_namespace','string','0','1','false'};

The _type_info instructs WebServiceCallout how the serialization should occur.

The parameters in that array are:

  1. The XML Element name
  2. The namespace for that element
  3. The XML Type
  4. minOccurs
  5. maxOccurs - -1 is unbound
  6. nillable (true/false)

The only thing that could possibly help in that list is the XML Type, but the CData tag is just a string that shouldn't be escaped.

I see that you don't want to use XMLStreamWriter as a work around, but since you are already using the FuseIT SFDC Explorer to process the WSDL to Apex this might make life easier.

When selecting the methods to generate code for, change the "Select Method Type" to "SOAP and HTTP".

enter image description here

That will generate an additional version of the method with a _Http() suffix. This will manually build and the SOAP request via the XML DOM and then parse the response as well. It is unlikely to handle CDATA escaping any better as generated. It will however give you lower level access to correct the escaping that is occurring.

1
  • 1
    Thanks for your answer. SFDX Explorer is a very handy tool. After creating the XML document I converted it to a String and replaced the CDATA tags to the decoded version. I used req.setBody(xmlString); instead of req.setBodyDocument(xmlDocument); which worked out fine.
    – epanzer
    Oct 11, 2018 at 14:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .