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>
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>
SUP expects the XML in a very specific format so I had to traverse through the multi-refs in the response using the for-each construct:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//ns1:getProjectsNoSchemesResponse">
<data>
<Record>
<Field op_label="id" op_position="1" op_datatype="STRING" op_nullable="true">id</Field>
<Field op_label="name" op_position="2" op_datatype="STRING" op_nullable="true">name</Field>
<Field op_label="description" op_position="3" op_datatype="STRING" op_nullable="true">description</Field>
</Record>
<xsl:for-each select="//ns1:getProjectsNoSchemesResponse/getProjectsNoSchemesReturn/href*">
<Record>
<Field>
<xsl:attribute name="op_label">id</xsl:attribute>
<xsl:attribute name="op_position">1</xsl:attribute>
<xsl:attribute name="op_datatype">STRING</xsl:attribute>
<xsl:attribute name="op_nullable">true</xsl:attribute>
<xsl:value-of select="getProjectNoSchemesReturn/id" />
</Field>
<Field>
<xsl:attribute name="op_label">name</xsl:attribute>
<xsl:attribute name="op_position">2</xsl:attribute>
<xsl:attribute name="op_datatype">STRING</xsl:attribute>
<xsl:attribute name="op_nullable">true</xsl:attribute>
<xsl:value-of select="getProjectNoSchemesReturn/name" />
</Field>
<Field>
<xsl:attribute name="op_label">description</xsl:attribute>
<xsl:attribute name="op_position">3</xsl:attribute>
<xsl:attribute name="op_datatype">STRING</xsl:attribute>
<xsl:attribute name="op_nullable">true</xsl:attribute>
<xsl:value-of select="getProjectNoSchemesReturn/name" />
</Field>
</Record>
</xsl:for-each>
</data>
</xsl:template>
</xsl:stylesheet>
精彩评论