tags:

views:

57

answers:

2

I am generating WSDL from XSD with XSLT 2.0, and I am copying the schema directly into the WSDL like so:

    ....
    <!-- WSDL types  -->
    <xsl:template name="types">
        <wsdl:types>
            <xsl:copy-of select="/xsd:schema"/>
        </wsdl:types>
    </xsl:template>
    .... 

Now I also want to append some types within the schema element, what is the best way to do this.

I am using this XSLT as a baseline in my work.

+3  A: 

You need to change the way you're processing the xsd:schema. Currently you are just doing a straight copy which makes it impossible to alter the content of the xsd:schema node.

What you need to do is to change your xsl:copy-of to xsl:apply-templates. Doing so will let you modify the content any way you like by just writing appropriate matching templates and at the same time just copy the content you don't wanna modify by using an identity template:

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

Preferably, you could use a mode for your processing to make sure you're only affecting the nodes you want (see my comment at the end of the post):

....
<!-- WSDL types  -->
<xsl:template name="types">
  <wsdl:types>
    <xsl:apply-templates select="/xsd:schema" mode="schema"/>
  </wsdl:types>
</xsl:template>
....

Using this setup there would be no difference from using your xsl:copy-of. But now you could easily add, change, or modify the descendent nodes of /xsd:schema. For example, adding a child to xsd:schema could easily be done with:

<xsl:template match="xsd:schema" mode="schema">
  <xsl:copy>
    <!-- This will ensure further processing. -->
    <xsl:apply-templates select="@*|node()" mode="#current"/>
    <!-- Adds a child node to xsd:schema. -->
    <xsd:element name="...">
      ...
    </xsd:element>
  </xsl:copy>
</xsl:template>

Haven't worked with WSDL myself though, so I hope I haven't missunderstood you now!


Edit: Sorry, you don't need a mode to simplify the processing. I read your question wrong and though that the input document was something else but a XSD. It won't hurt, but it won't help you very much either.

Per T
+1 for a good answer and good explanation.
Dimitre Novatchev
+1 Good answer.
Alejandro
+1  A: 

Just use:

<!-- WSDL types  --> 
<xsl:template name="types"> 
    <wsdl:types>
       <xsl:for-each select="/xsd:schema">
        <xsl:copy>
          <xsl:copy-of select="node()|@*"/>

          <!-- Add your additional types here, for example:  -->
          <xsl:copy-of select="$vMyNewTypes"/>
        <xsl:copy>
       </xsl:for-each> 
    </wsdl:types> 
</xsl:template> 
Dimitre Novatchev