I am trying to get CSV data from an XML document in the most efficient time using XSLT. Below is an example of XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<sObjects xmlns="urn:sobject.partner.soap.sforce.com">
<sObject>
<Name>Raagu</Name>
<BillingStreet>Hoskote</BillingStreet>
</sObject>
<sObject>
<Name>Rajath</Name>
<BillingStreet>BTM</BillingStreet>
<age>25</age>
</sObject>
<sObject>
<Name>Sarath</Name>
<BillingStreet>Murgesh</BillingStreet>
<location>Bangalore</location>
<age>#N/A</age>
</sObject>
<sObject>
<Name>Bharath</Name>
<BillingStreet>EGL</BillingStreet>
<location>Bangalore</location>
<shipping>Hoskote</Shipping>
</sObject>
<sObject>
<Id>12312321321</Id>
<Name>Guru</Name>
<location>Sirsi</location>
<date>12-12-12</date>
</sObject>
<sObject>
<Name>Appa</Name>
<BillingStreet>someStrrt</BillingStreet>
<accountNo>213213</accountNo>
</sObject>
<sObject>
<Name>Sarath</Name>
<BillingStreet>Murgesh</BillingStreet>
<location>Bangalore</location>
</sObject>
<sObject>
<Name>Sarath</Name>
<BillingStreet>Murgesh</BillingStreet>
<location>Bangalore</location>
</sObject>
<sObject>
<Name>Sarath</Name>
<BillingStreet>Murgesh</BillingStreet>
<location>Bangalore</location>
</sObject>
and I need a conclusion of this kind
<?xml version="1.0" encoding="utf-8"?><csv xmlns="http://www.approuter.com/schemas/RootNode"><data>Name,BillingStreet,age,location,Shipping,Id,date,accountNo
Raagu,Hoskote,,,,,,
Rajath,BTM,25,,,,,
Sarath,Murgesh,#N/A,Bangalore,,,,
Bharath,EGL,,Bangalore,Hoskote,,,
Guru,,,Sirsi,,12312321321,12-12-12,
Appa,someStrrt,,,,,,213213
Sarath,Murgesh,,Bangalore,,,,
Sarath,Murgesh,,Bangalore,,,,
Sarath,Murgesh,,Bangalore,,,,</data></csv>
To do this, I tried to execute XSLT
<xsl:stylesheet version="1.0" xmlns:p0="urn:sobject.partner.soap.sforce.com" xmlns:csv="csv:csv" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="xml"/>
<xsl:strip-space elements="*" />
<xsl:variable name="delimiter" select="','"/>
<xsl:key name="field" match="p0:sObject/*" use="name()"/>
<xsl:variable name="allFields"
select="/*/*/*[generate-id()=generate-id(key('field', name())[1])]"/>
<xsl:template match="/">
<xsl:element name="csv" namespace="http://www.approuter.com/schemas/RootNode">
<xsl:element name="data" namespace="http://www.approuter.com/schemas/RootNode">
<xsl:for-each select="$allFields">
<xsl:value-of select="name()" />
<xsl:if test="position() < last()">
<xsl:value-of select="$delimiter" />
</xsl:if>
</xsl:for-each>
<xsl:text>
 </xsl:text>
<xsl:apply-templates select="/*/p0:sObject" />
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="p0:sObject">
<xsl:variable name="this" select="." />
<xsl:for-each select="$allFields">
<xsl:value-of select="$this/*[name() = name(current())]" />
<xsl:if test="position() < last()">
<xsl:value-of select="$delimiter" />
</xsl:if>
</xsl:for-each>
<xsl:if test="position() < last()">
<xsl:text>
 </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The above XSLT works great in terms of functionality. But I'm trying to process about 10,000 records. i, e 10000 instances on sObject elements, each sObject will contain about 15 fields below it.
If I ran this above XSLT to handle these many records, it will depend. XSLT takes about 20 minutes to process and transmit csv data. I wanted to do it in seconds. This means that XSLT takes from 3-4 seconds to process 10k records (sObject records) to provide reliable CSV data, as shown above.
, XSLT XSLT, .