From an XML document:
<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>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#_f9daea33-e32a-4dde-beb4-d5227690b1a3">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="#default samlp saml ds xs xsi"
xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>uL1LoegsT53UGJE/HQqG9VW1Mnc=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>ifdW4P9/</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIHwzCCBaugAwIBAgIKeH+</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<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:Issuer>urn:jh:identityprovider</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
>ZQA|brandtest</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2015-07-30T16:06:59.331Z"
Recipient="https://jacksonhewitt.brandmuscle.net/Login/PAuthentication.aspx?configSet=SAML"
/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2015-07-30T14:06:59.331Z"
NotOnOrAfter="2015-07-30T16:06:59.331Z">
<saml:AudienceRestriction>
<saml:Audience>https://domain.net/Login/PAuthentication.aspx?configSet=SAML</saml:Audience>
<saml:Audience>https://domain.net/</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AttributeStatement>
<saml:Attribute Name="Phone"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue>867-5309</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<saml:AttributeStatement>
<saml:Attribute Name="Phone2"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue>555-1212</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<saml:AuthnStatement AuthnInstant="2015-07-30T15:06:59.335Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
XSLT Document:
<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']/*">
<!--This one works -->
<xsl:if test="(@Name='Phone')">
<xsl:variable name="phone" select="*[local-name() = 'AttributeValue']" />
<xsl:value-of select="$phone"/>
</xsl:if>
<!--This one doesn't work -->
<xsl:variable name="phone2" select="samlp:AttributeValue[../@Name = 'Phone2']" />
<xsl:value-of select="$phone2"/>
</xsl:for-each>
</USERINFO>
</AUTHENTICATOR>
</xsl:template>
</xsl:stylesheet>
When trying to output the value of the variable, it is empty. I'm guessing my 'select' syntax in the xsl:variable is incorrect?
I am able to get it to work like using the code below, but I don't want to have to use the 'if'.
<xsl:if test="(@Name='Phone')">
<xsl:variable name="phone" select="*[local-name() = 'AttributeValue']" />
<xsl:value-of select="$phone"/>
</xsl:if>
AttributeValue is an element and not an attribute, despite its misleading name ;) So use
*[@Name='Phone']/saml:AttributeValue
If for any reason you don't want to use prefixes and don't want to use if, you can use the following:
The key issue here is what the focus is. While the answer of proycon shows that you have used the attribute axis (with
@
), to access an element node, and that you forgot to use the namespace prefix, if you do not get the value, the focus may not be onsaml:Attribute
. Without seeing the rest of the code, it is hard to tell where it goes wrong.Suppose you have this:
then the template would never be matched, because it is not in the correct namespace. But even if you fix this to be
match="saml:Attribute"
, your variable starts with*
, which is short forchild::*
, and there is no child with an attributeName
undersaml:Attribute
.Suppose you have this:
then your focus is on some other node
Xyz
.To fix it, you need the surrounding focus-setting expression (
xsl:template
orxsl:for-each
) to select the parent ofsaml:Attribute
, or you need to address the expression itself if the focus is something else. The following would work, depending on the rest of your stylesheet (i.e., whether or not you applied templates to this node or not, here shown as a shallow-skip pattern):Only outputs the phone number(s):
Update (after your Q. update)
While I typed my answer, you said you did not want to use
xsl:if
and that you got it to work with the following code:A few points of interest:
local-name()
, if a direct NameTest suffices, in this casesaml:AttributeValue
(don't forget to add the namespace to thexsl:stylesheet
root element)xsl:if/@test
are redundantYou are right, you do not need
xsl:if
. You can simply change your variable to point tosaml:AttributeValue[../@Name='Phone']
, which will select nothingness, unless its parent hasPhone
in theName
attribute. 0. In other words, this is the same: