XSLT for WSDL reduction

S

Scott Sauyet

I'm trying to select a subset of a WSDL document using XSLT and a
simple text document describing the high-level elements to include. I
have it working fine for selecting the services, bindings, portTypes,
and messages to use. But I'm stumped on how to get the xs:simpleType
and xs:complexType elements filtered properly. I am not trying to do
this in a generic way. The WSDL is generated by a tool in our backend
system, and I know a fair bit about its structure, although I have no
control over it.

I am neither a novice nor an expert with XSLT. I don't use it much,
though, and I'm sure it shows. Any advice would be appreciated. If I
have to resort to doing this in code, I will, but I thought XSLT would
be up to the job...

I posted a sample WSDL with only one high-level service in it. It
represents both the input and the expected output format:

http://scott.sauyet.com/issues/2007-05-24/temp.wsdl


I import the text file (a whitespace separated list of service names)
and store it in a string simply by

<!DOCTYPE xsl:stylesheet [
<!ENTITY service-list SYSTEM "services.txt">
]>

<xsl:variable name="list">
<xsl:call-template name="normalize">
<xsl:with-param name="data">&service-list;</xsl:with-
param>
</xsl:call-template>
</xsl:variable>

<xsl:template name="normalize">
<xsl:param name="data" />
<xsl:value-of select="concat(normalize-space($data), ' ')" />
</xsl:template>

And I use a similar technique to define "service-list", which is the
same list with "Service" appended to each name.

Inside my main template, I can then use this to define the services to
choose:

<xsl:for-each select="wsdl:service">
<xsl:if test="contains($service-list, @name)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>

And I can select portTypes just as simply:

<xsl:for-each select="wsdl:portType">
<xsl:if test="contains($list, @name)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>

Bindings are slightly more complex:

<xsl:for-each select="wsdl:binding">
<xsl:variable name="bindName" select="concat('tns:', @name)"/>
<xsl:if test="count(../wsdl:service/wsdl:port[@binding=
$bindName and contains($service-list, ../@name)]) > 0">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>

And messages are getting scary:

<xsl:for-each select="wsdl:message">
<xsl:variable name="messName" select="concat('tns:', @name)"/>
<xsl:if test="count(../wsdl:portType/wsdl:eek:peration/
wsdl:input[@message=$messName and contains($list, ../../@name)] | ../
wsdl:portType/wsdl:eek:peration/wsdl:eek:utput[@message=$messName and
contains($list, ../../@name)]) > 0">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>

But I can't really figure out any way to get to, say, the complexTypes
required. What I want, in essence, is to display a complex type C
if there is a message M with a part P where P/@type = C.name and there
exists a portType T with an operation O with an input I where I/
@message = M/@name. (And this is a simplification?!) But I can't see
how to express that in XPath.

Any suggestions?

Thanks,

-- Scott Sauyet
 
I

Ixa

But I can't really figure out any way to get to, say, the complexTypes
required.

Just use the same method as with others: XPath predicates for
appropriate elements.
to display a complex type C

So, use normal XPath to get those elements and store name to variable.

---8<---8<---
<xsl:for-each select="/wsdl:definitions/wsdl:types/xs:schema/xs:complexType">
if there is a message M with a part P where P/@type = C.name and there
exists a portType T with an operation O with an input I where
I/@message = M/@name

Use two predicates:

* verify that there is a message that has the same name
* verify that there is an equal message elsewhere

---8<---8<---
<xsl:if test="/wsdl:definitions/wsdl:message[wsdl:part/@type =
$C.name][concat('tns:', @name) =
/wsdl:definitions/wsdl:portType/wsdl:eek:peration/wsdl:input/@message]">
---8<---8<---
 
S

Scott Sauyet

<xsl:for-each select="/wsdl:definitions/wsdl:types/xs:schema/xs:complexType">


Use two predicates:

* verify that there is a message that has the same name
* verify that there is an equal message elsewhere

I just noted that my very long response to this from earlier in the
week managed to disappear.

Thank you for your help, Ixa. I did settle on a different solutions,
but I learned some techniques from yours.

-- Scott
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top