471,338 Members | 1,302 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,338 software developers and data experts.

XSLT for WSDL reduction

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:operation/
wsdl:input[@message=$messName and contains($list, ../../@name)] | ../
wsdl:portType/wsdl:operation/wsdl:output[@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

May 24 '07 #1
2 3646
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">
<xsl:variable name="C.name" select="concat('ro:', @name)"/>
---8<---8<---
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:operation/wsdl:input/@message]">
---8<---8<---

--
Ixa

May 27 '07 #2
On May 26, 2:09 am, Ixa <i...@niksula.hut.fiwrote:
<xsl:for-each select="/wsdl:definitions/wsdl:types/xs:schema/xs:complexType">
<xsl:variable name="C.name" select="concat('ro:', @name)"/>
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
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

May 31 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

24 posts views Thread by Generic Usenet Account | last post: by
4 posts views Thread by Ringo Langly | last post: by
reply views Thread by Elhanan | last post: by
9 posts views Thread by Cesar | last post: by
5 posts views Thread by Nick K. | last post: by
11 posts views Thread by =?ISO-8859-1?Q?Jean=2DFran=E7ois_Michaud?= | last post: by
2 posts views Thread by astroboiii | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.