PixelPaul
PixelPaul

Reputation: 2767

XSLT: concatenate two field values if not null

I need to modify and existing XML document to concatenate to field values. I'm not sure how to do this, as I'm unable to keep the variables in scope.

Basically if there is a value present for FirstName and LastName, it should output FirstName+LastName. If either or both values for FirstName or LastName are empty, it should not output the FullName. Note this is an existing document and I am unable to modify any existing code above line #34.

Here is what I have so far:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <xsl:template match="/">
    <AUTHENTICATOR>
        <USERINFO>
            <xsl:for-each select="/samlp:Response/*[local-name() = 'Assertion']/*[local-name() = 'AttributeStatement']/*">

                <xsl:if test="@Name='First_Name'">
                    <xsl:variable name="firstname" select="*[local-name() = 'AttributeValue']" />
                    <xsl:element name="field">  
                        <xsl:attribute name="name">FirstName</xsl:attribute>    
                        <xsl:attribute name="value">    
                            <xsl:for-each select="*[local-name() = 'AttributeValue']">  
                                <xsl:value-of select="normalize-space(current())"/> 
                            </xsl:for-each> 
                        </xsl:attribute> 
                    </xsl:element> 
                </xsl:if>

                <xsl:if test="@Name='Last_Name'">
                    <xsl:variable name="lastname" select="*[local-name() = 'AttributeValue']" />
                    <xsl:element name="field">  
                        <xsl:attribute name="name">LastName</xsl:attribute>     
                        <xsl:attribute name="value">    
                            <xsl:for-each select="*[local-name() = 'AttributeValue']">  
                                <xsl:value-of select="normalize-space(current())"/> 
                            </xsl:for-each> 
                        </xsl:attribute> 
                    </xsl:element> 
                </xsl:if>

                <!-- Unable to modify anything above this line-->
                <!-- if firstname & lastname not null, concatinate firstname + lastname-->
                <xsl:if test="not($firstname = '') or not($lastname = '')">
                    <xsl:element name="field">
                        <xsl:attribute name="name">FullName</xsl:attribute>
                        <xsl:attribute name="value">
                            <xsl:value-of select="concat($firstname,'+',$lastname)" />
                        </xsl:attribute>
                    </xsl:element>
                </xsl:if>

            </xsl:for-each>

        </USERINFO>
    </AUTHENTICATOR>
  </xsl:template>
</xsl:stylesheet>

Simplified XML file below:

<samlp:Response ID="_f9daea33-e32a-4dde-beb4-d5227690b1a3" Version="2.0" IssueInstant="2015-07-30T15:06:58.874Z" Destination="https://domain.net/Login/PAuthentication.aspx?configSet=SAML" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:jh:identityprovider</saml:Issuer>
<samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<saml:Assertion Version="2.0" ID="_b54ca592-4401-4107-a426-281918091842" IssueInstant="2015-07-30T15:06:58.898Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:AttributeStatement>
        <saml:Attribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
            <saml:AttributeValue>John</saml:AttributeValue>
        </saml:Attribute>
    </saml:AttributeStatement>
            <saml:AttributeStatement>
        <saml:Attribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
            <saml:AttributeValue>Doe</saml:AttributeValue>
        </saml:Attribute>
    </saml:AttributeStatement>
</saml:Assertion>

Upvotes: 0

Views: 2709

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116982

The example is rather confusing - it's not clear what is a "record" and how many records can you have (judging by your XSLT, only one?).

See if you can use this as your starting point. It assumes each saml:Assertion is a record, and it outputs a FullName field if the record has both a FirstName and a LastName.

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
exclude-result-prefixes="samlp saml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/samlp:Response">
    <AUTHENTICATOR>
        <xsl:for-each select="saml:Assertion">
            <USERINFO>
                <xsl:variable name="firstname" select="saml:AttributeStatement/saml:Attribute[@Name='FirstName']/saml:AttributeValue"/>
                <xsl:variable name="lastname" select="saml:AttributeStatement/saml:Attribute[@Name='LastName']/saml:AttributeValue"/>
                <xsl:if test="$firstname and $lastname">
                    <field name="FullName" value="{concat($firstname, ' ', $lastname)}"/>  
                </xsl:if>
            </USERINFO>         
        </xsl:for-each>
    </AUTHENTICATOR>        
</xsl:template>

</xsl:stylesheet>

Test input

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
   <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
      <saml:AttributeStatement>
         <saml:Attribute Name="FirstName">
            <saml:AttributeValue>John</saml:AttributeValue>
         </saml:Attribute>
      </saml:AttributeStatement>
      <saml:AttributeStatement>
         <saml:Attribute Name="LastName">
            <saml:AttributeValue>Doe</saml:AttributeValue>
         </saml:Attribute>
      </saml:AttributeStatement>
   </saml:Assertion>
   <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
      <saml:AttributeStatement>
         <saml:Attribute Name="FirstName">
            <saml:AttributeValue>Madonna</saml:AttributeValue>
         </saml:Attribute>
      </saml:AttributeStatement>
   </saml:Assertion>
</samlp:Response>

Result

<?xml version="1.0" encoding="UTF-8"?>
<AUTHENTICATOR>
  <USERINFO>
    <field name="FullName" value="John Doe"/>
  </USERINFO>
  <USERINFO/>
</AUTHENTICATOR>

Note the use of prefixes to call out the elements in the source XML.

Upvotes: 1

Related Questions