Question

I have an source schema with a node forenames (containing forename + ' ' + middlename), which I need to separate out the middle name in the destination schema so this goes out to OtherNames.

I currently have the following xslt template:

<xsl:template name="StringSplit">
<xsl:param name="valFirstnames" />

<xsl:choose>
  <xsl:when test="contains($valFirstnames, ' ')">
      <xsl:call-template name="StringSplit">
        <xsl:with-param name="valFirstnames" select="substring-after($valFirstnames, ' ')" />
      </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
     <OtherFirstNames><xsl:value-of select="$valFirstnames" /></OtherFirstNames>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

Current output for this xslt template is writing out the Middlename twice rather than once:

<OtherFirstName>Middlename</OtherFirstName>
<OtherFirstName>Middlename</OtherFirstName>

Expected:

<OtherFirstName>Middlename</OtherFirstName>

Sample Input

<Data>
  <SubjectName>
    <forenames>first middle</forenames>
  </SubjectName>
  <SubjectPartner>
    <forenames>first middle</forenames>
    <Otherforenames>first middle</Otherforenames>
  </SubjectPartner>
  <etc./>
</Data>

Sample Output

<Data>
  <SubjectName>
    <firstname>first</firstname>
    <OtherFirstName>middle</OtherFirstname>
  </SubjectName>
  <SubjectPartner>
    <firstname>first</firstname>
    <OtherFirstName>middle</OtherFirstName>
    <OtherFirstName>middle</OtherFirstName>
  </SubjectPartner>
  <etc./>
</Data>

I'm looking at correcting the current xslt and updating to incorporate other partner elements that have the same child elements forenames.

Was it helpful?

Solution

Your examples do not make much sense to me. I am guessing you want to do something like:

XSLT 1.0

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

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

<xsl:template match="forenames">
    <firstname><xsl:value-of select="substring-before(concat(., ' '), ' ')"/></firstname>
    <xsl:if test="contains(., ' ')">
        <OtherFirstName><xsl:value-of select="substring-after(., ' ')"/></OtherFirstName>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Note that this assumes a person has at most two forenames. When applied to the following test input:

<Data>
    <SubjectName>
        <forenames>Alan Benjamin</forenames>
        <surname>Adams</surname>
    </SubjectName>
    <SubjectPartner>
        <forenames>Cecily Diana</forenames>
        <surname>Crown</surname>
    </SubjectPartner>
    <Single>
        <forenames>Eve</forenames>
        <surname>Evans</surname>
    </Single>
    <Triple>
        <forenames>Frank George Herbert</forenames>
        <surname>Forrester</surname>
    </Triple>
</Data>

the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
   <SubjectName>
      <firstname>Alan</firstname>
      <OtherFirstName>Benjamin</OtherFirstName>
      <surname>Adams</surname>
   </SubjectName>
   <SubjectPartner>
      <firstname>Cecily</firstname>
      <OtherFirstName>Diana</OtherFirstName>
      <surname>Crown</surname>
   </SubjectPartner>
   <Single>
      <firstname>Eve</firstname>
      <surname>Evans</surname>
   </Single>
   <Triple>
      <firstname>Frank</firstname>
      <OtherFirstName>George Herbert</OtherFirstName>
      <surname>Forrester</surname>
   </Triple>
</Data>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top