1
votes

I want to transform a source xml into a target xml where certain matches from the source xml are included in different context in the target xml. For example I have a source xml like:

<shiporder>
  <shipto>orderperson1</shipto>
  <shipto>orderperson1</shipto>
  <city>London</city>
</shiporder>

On this source xml I apply the following stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
     <xsl:call-template name="root" />
  </xsl:template>

  <xsl:template name="root">
    <root>
        <xsl:apply-templates select="/shiporder"/>
        <xsl:call-template name="Customer"/>
    </root>
</xsl:template>

 <xsl:template name="Customer">
    <Customer>
        <!--<xsl:apply-templates select="/shiporder"/>-->
    </Customer>
</xsl:template>

 <xsl:template match="/shiporder">
 <xsl:apply-templates select="shipto"/>
 </xsl:template>

 <xsl:template match="/shiporder/shipto">
    <Address>
        <xsl:apply-templates select="text()"/>
    </Address>
 </xsl:template>
</xsl:stylesheet>

In the template of name Customer I like to apply a template like:

 <xsl:template match="/shiporder">
 <xsl:apply-templates select="city"/>
 </xsl:template>

 <xsl:template match="/shiporder/city">
    <City>
        <xsl:apply-templates select="text()"/>
    </City>
 </xsl:template>

But I already defined a template with match /shiporder. So I don't know how to design a stylesheet where both templates with the same match exists in their own context?

1
Your question is ambiguous. 1) /shiporder can never really match anything, because apparently your document starts at /root. Please use working code for examples. Even if it does not produce the right results - it should not contain mistakes like that. 2) You did not say what output you expect. Please include an output that matches the input sample.Tomalak
@Tomalak I dont understand your complaining under point 1) please see the working example hereStellaMaris

1 Answers

1
votes

If you use mode, like @michael.hor257k suggested you can differentiate between two or more templates that match on the same element but with different results.

In your case that could end up looking like this:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
     <xsl:call-template name="root" />
  </xsl:template>

  <xsl:template name="root">
    <root>
        <xsl:apply-templates select="/shiporder" mode="root"/>
        <xsl:call-template name="Customer"/>
    </root>
</xsl:template>

 <xsl:template name="Customer">
    <Customer>
        <xsl:apply-templates select="/shiporder" mode="customer"/>
    </Customer>
</xsl:template>

 <xsl:template match="/shiporder" mode="root">
 <xsl:apply-templates select="shipto"/>
 </xsl:template>

  <xsl:template match="/shiporder" mode="customer">
 <xsl:apply-templates select="city"/>
 </xsl:template>

 <xsl:template match="shipto">
    <Address>
        <xsl:apply-templates select="text()"/>
    </Address>
 </xsl:template>

  <xsl:template match="city">
    <City>
        <xsl:apply-templates select="text()"/>
    </City>
 </xsl:template>

</xsl:stylesheet>

Obviously all credits here go to Michael for pointing this out first.