Re: [xsl] XSLT to populate a SAML AttributeStatement from an XML

Subject: Re: [xsl] XSLT to populate a SAML AttributeStatement from an XML
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 19 Jan 2023 07:50:23 -0000
Am 1/19/2023 um 8:41 AM schrieb ohaya ohaya@xxxxxxxxx:
Hi Martin,

Actually I think that even without the difference in the name, I am
going to have to do one template match per attribute.

I didn't post the entire XSLT, but the reason that I am saying that is
that in the XML that is the source, not all have the same path (e.g.
there is personnel, enterprise).

So given that, can you (or someone) post a single template match
including the tokenize()?


You can transform e.g.

<record>
B  <adrRecord>
B B B  <PN_ID>1111111</PN_ID>
B B B  <personnel>
B B B B B  <ADM_ORG_CD>urn:NORM:DEPT</ADM_ORG_CD>
B B B B B  <DOD_ASSOC_CD>urn:NORM:V01</DOD_ASSOC_CD>
B B B  </personnel>
B  </adrRecord>
</record>



with XSLT 3

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>

<xsl:mode on-no-match="shallow-skip"/>

<xsl:output indent="yes"/>

<xsl:template match="/">
B  <saml:AttributeStatement>
B B B  <xsl:apply-templates />
B  </saml:AttributeStatement>
</xsl:template>

<xsl:template match="record/adrRecord//*[not(*)]">
B  <saml:Attribute Name="{name()}">
B B B  <xsl:for-each select="tokenize(., ':')">
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">
B B B B B B B  <xsl:value-of select="."/>
B B B B B  </saml:AttributeValue>
B B B  </xsl:for-each>
B  </saml:Attribute>
</xsl:template>

</xsl:stylesheet>


into e.g.


<saml:AttributeStatement
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
B B  <saml:Attribute Name="PN_ID">
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">1111111</saml:AttributeValue>
B B  </saml:Attribute>
B B  <saml:Attribute Name="ADM_ORG_CD">
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">urn</saml:AttributeValue>
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">NORM</saml:AttributeValue>
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">DEPT</saml:AttributeValue>
B B  </saml:Attribute>
B B  <saml:Attribute Name="DOD_ASSOC_CD">
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">urn</saml:AttributeValue>
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">NORM</saml:AttributeValue>
B B B B B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">V01</saml:AttributeValue>
B B  </saml:Attribute>
</saml:AttributeStatement>


As you said XSLT 2 is available on the target platform you can't use the declaration

B <xsl:mode on-no-match="shallow-skip"/>


but have to spell out


<xsl:template match="/ | *">
B  <xsl:apply-templates select="@*"/>
B  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text() | @* | comment() | processing-instruction()"/>

Current Thread