Partager via


WSDL.EXE problem with BEA WSDL

As it turns out, using the 1.x builds of the .NET Framework, wsdl.exe (and
VS.NET) are sometimes unable to process perfectly good WSDL documents generated
from the latest versions of BEA WebLogic Workshop. If the WSDL contains
multiple schemas, and any have the same targetNamespace as another,
you'll get something like, "a schema with the namespace 'urn:foo-bar" has
already been added."

There are not currently plans to fix this behavior in the 1.x versions
of the framework. The product group is, however, planning to fix
it in 2.0 (although it's not yet in beta 1 yet). Since I know at least 2
large Microsoft customers have hit this problem, I thought someone else
might find this XSLT transform beneficial.

 <xsl:stylesheet version="1.0" 
  xmlns:xs="https://www.w3.org/2001/XMLSchema"
  xmlns:xsl="https://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" />
  <xsl:key name="matching-schemas" 
    match="xs:schema" use="@targetNamespace" />

  <xsl:template match="/|@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="xs:schema">
    <xsl:variable name="matches" 
      select="key('matching-schemas', @targetNamespace)" />
    <xsl:if test="count( . | $matches[1]) = 1">
      <xsl:apply-templates select="$matches[1]" mode="consolidate">
        <xsl:with-param name="matches" select="$matches" />
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <xsl:template match="xs:schema" mode="consolidate">
    <xsl:param name="matches" />
    <xs:schema>
      <xsl:apply-templates select="@*|node()" />
      <xsl:for-each select="$matches[position() != 1]">
        <xsl:apply-templates select="@*|node()" />
      </xsl:for-each>
    </xs:schema>
  </xsl:template>

</xsl:stylesheet>

I just threw it together and I've only tested it on a couple of
WSDLs ... so you might want to verify the results with yours, but I think
it's pretty solid.

At a higher level, this issue is usually a result of
developing the Web service using a code-first approach
in BEA WebLogic Workshop. As you will see is a common theme on this blog, I
recommend developing Web services using a contract-first approach whenever
possible, no matter what your platform.

I hope someone finds the transform useful. If you have any improvements or
comments about it, let's hear 'em.

Comments

  • Anonymous
    January 19, 2005
    I am having this problem. How do I use the XSLT to fix the problem?
  • Anonymous
    January 21, 2005
    I used disco which downloaded the wsdl and xsd and made a discomap. Next I used Saxon to run the transform shown here on the main wsdl file and replaced the main wsdl file with the output from running the transform. Next I ran WSDL.exe on the new wsdl file (with .NET version 1.1) and still came up with the duplicate namespace errors. What am I missing. Help, help...
  • Anonymous
    May 11, 2005
    RePost : http://www.yeyan.cn/Programming/WSDLWebServiceWebLogic.aspx
  • Anonymous
    December 01, 2005
    Just happened upon this post via a Google search for exactly this problem.

    The XSL works great, but it seems to swallow any embedded <xs:schema> element that doesn't have a targetNamespace. My XSLT isn't good enough to figure out why this occurs.