Search code examples
xsltsoapsup

Can a custom XSLT definition handle a SOAP response that returns an Array of Objects when defining an MBO?


I seem to have run into a limitation in SUP regarding its ability to handle a SOAP response containing a list of objects and I am wondering if it would be possible to write a custom XSLT to handle this. I am trying to make a call into Jira via the getProjectsNoSchemes method via SOAP. This method returns an array of RemoteProject objects. Ultimately I would like to be able to treat each node as a row in a table, but unfortunately I don't know enough about XSLT to be able to know if this is possible or not. I also don't know if this is even a viable solution in SUP.

A sample of the SOAP response is below:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
    <ns1:GetProjectsNoSchemesResponse
        soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:ns1="http://www.webserviceX.NET">
        <GetProjectsNoSchemesReturn
            soapenc:arrayType="ns2:RemoteProject[2]" xsi:type="soapenc:Array"
            xmlns:ns2="http://beans.soap.rpc.jira.atlassian.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
            <GetProjectsNoSchemesReturn href="#id0" />
            <GetProjectsNoSchemesReturn href="#id1" />
        </GetProjectsNoSchemesReturn>
    </ns1:GetProjectsNoSchemesResponse>
    <multiRef id="id0" soapenc:root="0"
        soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xsi:type="ns3:RemoteProject" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:ns3="http://beans.soap.rpc.jira.atlassian.com">
        <description xsi:type="xsd:string">Mobile Web Project POC
        </description>
        <id xsi:type="xsd:string">10034</id>
        <issueSecurityScheme xsi:type="ns3:RemoteScheme"
            xsi:nil="true" />
        <key xsi:type="xsd:string">XLIPOC</key>
        <lead xsi:type="xsd:string">benm</lead>
        <name xsi:type="xsd:string">Redacted Project</name>
        <notificationScheme xsi:type="ns3:RemoteScheme"
            xsi:nil="true" />
        <permissionScheme xsi:type="ns3:RemotePermissionScheme"
            xsi:nil="true" />
        <projectUrl xsi:type="xsd:string"></projectUrl>
        <url xsi:type="xsd:string">https://redacted.com/browse/REDACTED</url>
    </multiRef>
    <multiRef id="id1" soapenc:root="0"
        soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xsi:type="ns4:RemoteProject" xmlns:ns4="http://beans.soap.rpc.jira.atlassian.com"
        xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
        <description xsi:type="xsd:string"></description>
        <id xsi:type="xsd:string">10017</id>
        <issueSecurityScheme xsi:type="ns4:RemoteScheme"
            xsi:nil="true" />
        <key xsi:type="xsd:string">GIC</key>
        <lead xsi:type="xsd:string">gregm</lead>
        <name xsi:type="xsd:string">REDACTED</name>
        <notificationScheme xsi:type="ns4:RemoteScheme"
            xsi:nil="true" />
        <permissionScheme xsi:type="ns4:RemotePermissionScheme"
            xsi:nil="true" />
        <projectUrl xsi:type="xsd:string"></projectUrl>
        <url xsi:type="xsd:string">https://redacted.com/browse/REDACTED</url>
    </multiRef>
</soapenv:Body>


Solution

  • Yes, it's possible, and relatively easy to do so.

    Below is an example XSLT that produces an HTML document with a table row for each <multRef> element.

    Each child element of <multiRef> is first rendered as a table header using the name of the element for the heading column, and then each <multiRef> is rendered as rows with columns for each of the child elements:

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <html>
                <head></head>
                <body>
                    <table border="1">
                        <xsl:apply-templates select="*/*/multiRef[1]" mode="header"/>
                        <xsl:apply-templates select="*/*/multiRef" />
                    </table>
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="multiRef" mode="header">
            <thead>
                <tr>
                    <xsl:apply-templates mode="header"/>
                </tr>
            </thead>
        </xsl:template>
    
        <xsl:template match="multiRef/*" mode="header">
            <th>
                <xsl:value-of select="local-name()"/>
            </th>
        </xsl:template>
    
        <xsl:template match="multiRef">
            <tr>
                <xsl:apply-templates/>
            </tr>
        </xsl:template>
    
        <xsl:template match="multiRef/*">
            <td>
                <xsl:apply-templates/>
            </td>
        </xsl:template>
    </xsl:stylesheet>
    

    When applied to the sample XML provided, it produces the following HTML:

    <html>
        <head>
        <META http-equiv="Content-Type" content="text/html; charset=UTF-16">
        </head>
        <body>
            <table border="1">
                <thead>
                    <tr>
                        <th>description</th>
                        <th>id</th>
                        <th>issueSecurityScheme</th>
                        <th>key</th>
                        <th>lead</th>
                        <th>name</th>
                        <th>notificationScheme</th>
                        <th>permissionScheme</th>
                        <th>projectUrl</th>
                        <th>url</th>
                    </tr>
                </thead>
                <tr>
                    <td>Mobile Web Project POC
                    </td>
                    <td>10034</td>
                    <td></td>
                    <td>XLIPOC</td>
                    <td>benm</td>
                    <td>Redacted Project</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>https://redacted.com/browse/REDACTED</td>
                </tr>
                <tr>
                    <td></td>
                    <td>10017</td>
                    <td></td>
                    <td>GIC</td>
                    <td>gregm</td>
                    <td>REDACTED</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>https://redacted.com/browse/REDACTED</td>
                </tr>
            </table>
        </body>
    </html>