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

Subject: Re: ALMOST WORKING was Re: [xsl] XSLT to populate a SAML AttributeStatement from an XML
From: "Bauman, Syd s.bauman@xxxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 19 Jan 2023 17:22:26 -0000
While the gateway platform on which you are running the XSLT may well have
2.0 capability, the stylesheet itself says it is 1.0. My system, at least,
will not allow me to use a 2.0 function (tokenize()) in a 1.0 stylesheet.

But after converting the "1.0" to "2.0" I tried running, and indeed the
1111111 and urn:NORM:V01 are in the output.

Here is the stylesheet (refactored a wee bit) with line numbers:
01|  <?xml version="1.0" encoding="UTF-8"?>
02|  <xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
03|    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
04|    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
05|    xmlns:xsd="http://www.w3.org/2001/XMLSchema"; >
06|
07|    <xsl:template match="/">
08|      <saml:AttributeStatement>
09|        <xsl:apply-templates select="/record/adrRecord/*"/>
10|      </saml:AttributeStatement>
11|    </xsl:template>
12|
13|    <xsl:template match="/record/adrRecord/personnel/ADM_ORG_CD">
14|      <saml:Attribute Name="MY_ORG_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
15|        <xsl:for-each select="tokenize(., ':')">
16|          <saml:AttributeValue xsi:type="xsd:string">
17|            <xsl:value-of select="."/>
18|          </saml:AttributeValue>
19|        </xsl:for-each>
20|      </saml:Attribute>
21|    </xsl:template>
22|
23|  </xsl:stylesheet>

Line 09 asks that all element children of /record/adrRecord be processed. What
it means (roughly speaking) to process an element is for the XSLT engine to
reach into the input tree and pick up each matching construct (in this case
the element children of /record/adrRecord, in document order), and for each
one ask the question is there a template that matches this?. If the answer
is yes, run that template on this construct (in this case an element). If
the answer is no, run the build-in template on this element.

The elements that are picked up to process are <PN_ID>, and <personnel>. For
neither is there a matching template. (The only template other than match
root matches /record/adrRecord/personnel/ADM_ORG_CD.) So in both cases, the
built-in template is run. The built-in template for elements says, basically,
process my children.

So the next step is for the XSLT engine to process the <PN_ID> with the
process my children built-in template. In this case, the one child is a
7-charcter long text node. That node is grabbed, and the XSLT engine asks the
question is there a template that matches this?. The answer is no, so the
engine hands the node over to the built-in template. The built-in template for
text nodes says (basically) put this in the output. Thus the output has the
string 1111111.

Roughly the same thing occurs with
/record/adrRecord/personnel/ADM_ORG_CD/DOD_ASSOC_CD. (No template, so the
built-in template is run instead.)

Seems to me (without thinking about it much) that this problem stems from the
mis-match between the @select on line 09 and the @match on line 13. Probably
reasonable to be specific on the @select
(/record/adrRecord/personnel/ADM_ORG_CD); also would be more readable if the
@match just matched the element (ADM_ORG_CD), although that might cause
problems iff there are other <ADM_ORG_CD> elements that you do not want to
match (and other code that might match them).

HTH.
________________________________

I tried the XSLT on the gateway, which does have XSLT 2.0. It looks like it
worked, but it's generating some "EXTRANEOUS" output... specifically,
it looks like is outputting the VALUE of some the other elements, I am not
sure why :(...

1-Here's the source XML:

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




2-Here's the XSLT:

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


<xsl:template match="/">
<saml:AttributeStatement>
<xsl:apply-templates select="/record/adrRecord/*"/>
</saml:AttributeStatement>
</xsl:template>

<xsl:template match="/record/adrRecord/personnel/ADM_ORG_CD">
<saml:Attribute Name="MY_ORG_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">

<xsl:for-each select="tokenize(.,':')">
<saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string"><xsl:value-of select="."/></saml:AttributeValue>
</xsl:for-each>
</saml:Attribute>
</xsl:template>


<!--
<xsl:template match="/record/adrRecord/personnel/ADM_ORG_CD">
<saml:Attribute Name="MY_ORG_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string"> <xsl:value-of
select="/record/adrRecord/personnel/ADM_ORG_CD" />
</saml:AttributeValue>
</saml:Attribute>
</xsl:template>

<xsl:template match="/record/adrRecord/personnel/DOD_ASSOC_CD">
<saml:Attribute Name="MY_ASSOC_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string"> <xsl:value-of
select="/record/adrRecord/personnel/DOD_ASSOC_CD" />
</saml:AttributeValue>
</saml:Attribute>

</xsl:template>
-->

</xsl:stylesheet>



3-Here's the output when I run the XSLT:

<?xml version="1.0" encoding="UTF-8"?><saml:AttributeStatement
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>1111111<saml:Attribute
Name="MY_PN_ID"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:Attribut
eValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">urn</saml:AttributeValue><saml:AttributeValue
xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">NORM</saml:AttributeValue><saml:AttributeValue
xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">DEPT</saml:AttributeValue></saml:Attribute>urn:NORM:V01
</saml:AttributeStatement>



NOTICE that it is outputting the "
1111111" and the "urn:NORM:V01".

Why is that?

Current Thread