Skip to content

Instantly share code, notes, and snippets.

@afawcett
Last active November 25, 2018 10:10
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afawcett/193cc9a29a96bb36c260f09a3cc0a043 to your computer and use it in GitHub Desktop.
Save afawcett/193cc9a29a96bb36c260f09a3cc0a043 to your computer and use it in GitHub Desktop.
Apex MD API and XSLT

Requirement

Perform XSLT transform on XML returned from the Salesforce Metadata API retrieve operation (also requires unzip). Based on the code in https://github.com/financialforcedev/apex-mdapi

Solution

Adapting the metadataretrieve.page in the above repository. The original page passed the client side unzipped files from the MD retrieve zip file back to the server to add to the view state for display. As the XSLT is done client side, the above page is much simpler, the unzipped files are just handled client side and added dynamically to the page DOM.

Implementaiton Notes

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="http://soap.sforce.com/2006/04/metadata" version="1.0">
<xsl:template match="/">
<h2>The Object's Fields</h2>
<table>
<xsl:for-each select="md:CustomObject/md:fields">
<tr>
<td>
<xsl:value-of select="md:fullName"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
<!--
/**
* Copyright (c) 2012, FinancialForce.com, inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
-->
<apex:page controller="MetadataRetrieveController" action="{!init}" sidebar="false">
<apex:includeScript value="{!URLFOR($Resource.jszip, '/jszip.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jszip, '/jszip-load.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jszip, '/jszip-deflate.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jszip, '/jszip-inflate.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.mxml)}"/> <!-- http://tomdavies.azurewebsites.net/magicxml/ -->
<script>
function unzipFile(path, data) {
// Transform?
if(path.endsWith('.object')) {
var transformedOutput = magicXML.transform(data, '{!URLFOR($Resource.mdtobjectxslt)}');
document.getElementById('files').
appendChild(transformedOutput);
} else { // Emit as is
var pre = document.createElement("PRE");
pre.appendChild(document.createTextNode(data));
document.getElementById('files').appendChild(pre);
}
// Function exposed by the c:unzip component, used to continue the unzip process
unzip();
}
function unzipComplete() { }
</script>
<apex:form id="form" >
<apex:sectionHeader title="Metadata Retrieve Demo"/>
<apex:pageMessages id="messages"/>
<apex:actionPoller action="{!checkAsyncRequest}" interval="5" rerender="form" rendered="{!NOT(ISNULL(AsyncResult))}"/>
<apex:pageBlock title="Layouts" rendered="{!AND(ISNULL(AsyncResult),ISNULL(MetaDataRetrieveZip))}">
<apex:pageBlockButtons >
<apex:commandButton value="List" action="{!listMetadataItems}" />
<apex:commandButton value="Retrieve" action="{!retrieveMetadataItem}" />
</apex:pageBlockButtons>
<apex:pageBlockSection columns="1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="Metadata Type:" />
<apex:selectList size="1" value="{!MetadataType}" >
<apex:selectOptions value="{!MetadataTypes}"/>
<apex:actionSupport event="onchange" action="{!listMetadataItems}"/>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Metadata Folder" />
<apex:inputText value="{!MetaDataFolder}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Metadata Item:" />
<apex:selectList size="1" value="{!MetaDataItem}" >
<apex:selectOptions value="{!MetaDataItems}"/>
</apex:selectList>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
</apex:pageBlock>
<apex:outputPanel rendered="{!NOT(ISNULL(MetaDataRetrieveZip))}">
<c:unzip name="unzip" oncomplete="if(more) unzipFile(path, data); else unzipComplete();">{!MetaDataRetrieveZip}</c:unzip>
</apex:outputPanel>
<apex:pageBlock title="Retrieved and Transformed Metadata Files">
<apex:pageBlockSection columns="1">
<div id="files"></div>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment