Skip to content

Instantly share code, notes, and snippets.

@trscavo
Created January 6, 2017 20:51
Show Gist options
  • Save trscavo/f42e59e8628a6b663a8c39654748cae4 to your computer and use it in GitHub Desktop.
Save trscavo/f42e59e8628a6b663a8c39654748cae4 to your computer and use it in GitHub Desktop.
Extract all entities with an SP role and a particular orgName into a CSV file
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2017 Internet2
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
list_all_org_SPs_csv.xsl
This XSL transform takes a SAML metadata aggregate and an orgName
parameter on the command line. It matches on every entity descriptor
with an SP role and the given orgName, and then produces a CSV file
with the following fields:
1. Entity ID: @entityID
2. Display Name: mdui:DisplayName
3. Description: mdui:Description
4. Information URL: mdui:InformationURL
5. Privacy Statement URL: mdui:PrivacyStatementURL
6. Technical Contacts: md:ContactPerson[@contactType = 'technical']
7. Administrative Contacts: md:ContactPerson[@contactType = 'administrative']
8. Support Contacts: md:ContactPerson[@contactType = 'support']
Note that if a field is blank, there is no corresponding metadata.
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
<!-- orgName required on the command line -->
<xsl:param name="orgName" required="yes"/>
<!-- search-and-replace constants -->
<xsl:variable name="double_quote" select="'&quot;'"/>
<xsl:variable name="double_double_quote" select="'&quot;&quot;'"/>
<!-- output is plain text -->
<xsl:output method="text"/>
<xsl:template match="/">
<!-- output the heading line -->
<xsl:text>Entity ID,Display Name,Description,Information URL,Privacy Statement URL,Technical Contacts,Administrative Contacts,Support Contacts</xsl:text>
<xsl:text>&#x0a;</xsl:text>
<!-- iterate over all entity descriptors with an SP role administered by UCOP -->
<xsl:for-each select="md:EntitiesDescriptor/md:EntityDescriptor[md:SPSSODescriptor and md:Organization/md:OrganizationName = $orgName]">
<!-- compute the normalized values of mdui:DisplayName and md:OrganizationDisplayName -->
<xsl:variable name="displayName" select="normalize-space(md:SPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en'])"/>
<xsl:variable name="description" select="normalize-space(md:SPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:Description[@xml:lang='en'])"/>
<!-- compute the values of mdui:InformationURL and md:PrivacyStatementURL -->
<xsl:variable name="informationURL" select="md:SPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:InformationURL[@xml:lang='en']"/>
<xsl:variable name="privacyStatementURL" select="md:SPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:PrivacyStatementURL[@xml:lang='en']"/>
<!-- output @entityID -->
<xsl:value-of select="@entityID"/>
<!-- output mdui:DisplayName -->
<xsl:text>,</xsl:text>
<xsl:if test="$displayName != ''">
<!-- escape literal double quotes in mdui:DisplayName -->
<xsl:variable name="escapedDisplayName">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="$displayName"/>
<xsl:with-param name="search" select="$double_quote"/>
<xsl:with-param name="replace" select="$double_double_quote"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>"</xsl:text>
<xsl:value-of select="$escapedDisplayName"/>
<xsl:text>"</xsl:text>
</xsl:if>
<!-- output mdui:Description -->
<xsl:text>,</xsl:text>
<xsl:if test="$description != ''">
<!-- escape literal double quotes in mdui:DisplayName -->
<xsl:variable name="escapedDescription">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="$description"/>
<xsl:with-param name="search" select="$double_quote"/>
<xsl:with-param name="replace" select="$double_double_quote"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>"</xsl:text>
<xsl:value-of select="$escapedDescription"/>
<xsl:text>"</xsl:text>
</xsl:if>
<!-- output mdui:InformationURL -->
<xsl:text>,</xsl:text>
<xsl:value-of select="$informationURL"/>
<!-- output mdui:PrivacyStatementURL -->
<xsl:text>,</xsl:text>
<xsl:value-of select="$privacyStatementURL"/>
<!-- output technical contacts -->
<xsl:text>,</xsl:text>
<xsl:for-each select="md:ContactPerson[@contactType = 'technical']">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
<xsl:when test="position() &gt; 1">
<xsl:text>; </xsl:text>
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- output administrative contacts -->
<xsl:text>,</xsl:text>
<xsl:for-each select="md:ContactPerson[@contactType = 'administrative']">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
<xsl:when test="position() &gt; 1">
<xsl:text>; </xsl:text>
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- output support contacts -->
<xsl:text>,</xsl:text>
<xsl:for-each select="md:ContactPerson[@contactType = 'support']">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
<xsl:when test="position() &gt; 1">
<xsl:text>; </xsl:text>
<xsl:value-of select="md:GivenName"/><xsl:text> &lt;</xsl:text><xsl:value-of select="md:EmailAddress"/><xsl:text>&gt;</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- output EOL -->
<xsl:text>&#x0a;</xsl:text>
</xsl:for-each>
</xsl:template>
<!--
A named template that performs global (recursive) search-and-replace on a string
(similar to fn:replace(string, pattern, replace) in XSLT 2.0).
See: http://stackoverflow.com/questions/3067113/xslt-string-replace/3067130#3067130
-->
<xsl:template name="string-replace-all">
<xsl:param name="string"/>
<xsl:param name="search"/>
<xsl:param name="replace"/>
<xsl:choose>
<xsl:when test="$string = '' or $search = '' or not($search)">
<!-- Prevent this routine from hanging -->
<xsl:value-of select="$string"/>
</xsl:when>
<xsl:when test="contains($string, $search)">
<xsl:value-of select="substring-before($string, $search)"/>
<xsl:value-of select="$replace"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="substring-after($string, $search)"/>
<xsl:with-param name="search" select="$search"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<!-- do nothing -->
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment