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

Subject: Re: [xsl] XSLT to populate a SAML AttributeStatement from an XML
From: "ohaya ohaya@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 18 Jan 2023 20:40:04 -0000
 I haven't worked with XSLT for years now, and as I said I don't mind breaking
this up into pieces.

I have been trying to get an XSLT to do the transformation on just the
<saml:Attribute> elements individually that are inside the
<saml:AttributeStatement>, and the output looks ok, but when I run it through
xsltproc, it is giving me an error. (this not even with trying to split up the
element values yet).

This is what I have so far:

The XML:

 <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>

My xslt (please don't laugh!):

<xsl:stylesheet version="1.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:template match="/record/adrRecord/PN_ID">
<saml:Attribute Name="MY_PN_ID"
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/PN_ID" />
 </saml:AttributeValue>
</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>


When I run that with xsltproc I get:

<?xml version="1.0"?>


 <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 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">1111111</saml:AttributeValue></saml:Attribute>

 <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; Name="MY_ORG_CD"
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:NORM:DEPT</saml:AttributeValue></saml:Attribute>
 <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; Name="MY_ASSOC_CD"
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:NORM:V01</saml:AttributeValue></saml:Attribute>





I don't know why there is that extra blank line after the first
<saml:Attribute>, but when I run xmllint --format I get:

:6: parser error : Extra content at the end of the document
 <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:x


What "extra content" is it referring to?

Thanks,
Jim


     On Wednesday, January 18, 2023, 03:06:03 PM EST, ohaya <ohaya@xxxxxxxxx>
wrote:

  Hi,

FYI, if/when I can get this working, the XSLT will be running on a Gateway
machine. I just checked, and I *can* select "2.0" for the XSLT, but I don't
see "2.0+".

Re. "attributes" - you are correct... I mispoke.

Thanks,
Jim


     On Wednesday, January 18, 2023, 01:56:13 PM EST, Michael Kay
<michaelkay90@xxxxxxxxx> wrote:

 Are you able to use XSLT 2.0+ -- that gives you a tokenize() function which
makes this far easier.

In 2.0 it's essentially

<xsl:template match="personnel/*">
B  <saml:Attribute Name="{name()}"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
B  B  <xsl:for-each select="tokenize(.)">
B  B  B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string"><xsl:value-of select="."/></saml:AttributeValue>

Incidentally, there are no attributes in your input XML - it's all elements.

Michael Kay
Saxonica
B 

> On 18 Jan 2023, at 17:06, ohaya ohaya@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> [I originally sent this to the wrong email address... sorry!]
>
> Hi,
>
> I have an application where I am retrieving a number of attributes and
values from a web service, in the form of an XML file, and I want to create
and populate a SAML AttributeStatement from the attributes and values in that
XML file.B  A couple of complications (to me):
>
> - The attribute names in the XML file are different than the corresponding
attributes in the SAML AttributeStatement.
> - Some of the attributes are multi-valued:B  in the source XML file, the
values are a colon-separated string (e.g. ab:cd:ef), but in the
AttributeStatement, each value will be in separate <saml:Attribute> element.
>
> Here's an example source XML:
>
> <record>
> .
> .
> .
>B  <adrRecord>
>B  B  <PN_ID>1111111</PN_ID>
>B  B  <personnel>
>B  B  B  <ADM_ORG_CD>urn:NORM:DEPT</ADM_ORG_CD>
>B  B  B  <DOD_ASSOC_CD>urn:NORM:V01</DOD_ASSOC_CD>
>B  B  </personnel>
>B  </adrRecord>
> </record>
>
> and the AttributeStatement I want to transform the above to is something
like:
>
>
>B  B  <saml:Attribute Name="MY_PN_ID"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
>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="MY_ORG_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
>B  B  B  B  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">DEPT</saml:AttributeValue>
>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  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">NORM</saml:AttributeValue>
>B  B  </saml:Attribute>
>
>
>B  B  <saml:Attribute Name="MY_ASSOC_CD"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
>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  <saml:AttributeValue xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xsi:type="xsd:string">NORM</saml:AttributeValue>
>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>
>
> Can someone suggest the best approach to do this?B  I actually would prefer
to have a series of transforms to do this, rather than just a single XSLT,
mainly so I can be able to see how things are working (or not working).
>
> Thanks,
> Jim

Current Thread