09-26-2014 10:04 AM
Does anyone have an XSL Transform worked out that conveniently parses the CPSC Form output from Service Link when it has a grid in it?
For example the data from CPSC Service Link might look like:
<root>
<Common>
<Action ClassID="">Some Action</Action>
<RequisitionID>123</RequisitionID>
...
</Common>
<Attributes/>
<FormData>
<Dictionary.Field>Some Data</Dictionary.Field>
<DictionaryWithGrid-1.Field1>somevalue</DictionaryWithGrid-1.Field1>
<DictionaryWithGrid-1.Field2>someothervalue</DictionaryWithGrid-1.Field2>
<DictionaryWithGrid-1.Field3>yetanothervalue</DictionaryWithGrid-1.Field3>
<DictionaryWithGrid-2.Field1>somevalue2</DictionaryWithGrid-2.Field1>
<DictionaryWithGrid-2.Field2>someothervalue2</DictionaryWithGrid-2.Field2>
<DictionaryWithGrid-2.Field3>yetanothervalue2</DictionaryWithGrid-2.Field3>
</FormData>
</root>
So the desired output would be
<Row>
<Field1>somevalue</Field1>
<Field2>someothervalue</Field2>
<Field3>yetanothervalue</Field3>
</Row>
<Row>
<Field1>somevalue2</Field1>
<Field2>someothervalue2</Field2>
<Field3>yetanothervalue2</Field3>
</Row>
I'm having difficulty getting the right XSL select when the tag is something like 'DictionaryWithGrid-#.Field'.
Thanks!
Solved! Go to Solution.
09-29-2014 07:05 AM
Try this...
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:template match="root">
<Table>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="1" />
</xsl:call-template>
</Table>
</xsl:template>
<xsl:template name="ProcessOne">
<xsl:param name="pos" />
<xsl:variable name="RowName" select="concat('DictionaryWithGrid-', $pos)" />
<xsl:if test="FormData/*[starts-with(name(), $RowName)] != ''">
<Row>
<xsl:for-each select="FormData/*[starts-with(name(), $RowName)]">
<xsl:if test="starts-with(name(.), $RowName)">
<xsl:variable name="FieldName" select="substring-after(name(.), '.')"/>
<xsl:element name="{$FieldName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</Row>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="number($pos+1)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
09-30-2014 06:19 AM
That worked great, Svetlana! Thank you very much for the help.
I made some slight mods to make it even more portable and intuitive for XSL/XML beginners.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<!-- Replace CHANGEME below with the name of the CPSC Form Dictionary to transform -->
<xsl:variable name="Dictionary">CHANGEME</xsl:variable>
<xsl:template match="root">
<Table>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="1" />
</xsl:call-template>
</Table>
</xsl:template>
<xsl:template name="ProcessOne">
<xsl:param name="pos" />
<xsl:variable name="RowName" select="concat($Dictionary, '-', $pos)" />
<xsl:if test="FormData/*[starts-with(name(), $RowName)] != ''">
<Row>
<xsl:for-each select="FormData/*[starts-with(name(), $RowName)]">
<xsl:if test="starts-with(name(.), $RowName)">
<xsl:variable name="FieldName" select="substring-after(name(.), '.')"/>
<xsl:element name="{$FieldName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</Row>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="number($pos+1)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
09-29-2014 07:05 AM
Try this...
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:template match="root">
<Table>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="1" />
</xsl:call-template>
</Table>
</xsl:template>
<xsl:template name="ProcessOne">
<xsl:param name="pos" />
<xsl:variable name="RowName" select="concat('DictionaryWithGrid-', $pos)" />
<xsl:if test="FormData/*[starts-with(name(), $RowName)] != ''">
<Row>
<xsl:for-each select="FormData/*[starts-with(name(), $RowName)]">
<xsl:if test="starts-with(name(.), $RowName)">
<xsl:variable name="FieldName" select="substring-after(name(.), '.')"/>
<xsl:element name="{$FieldName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</Row>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="number($pos+1)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
09-30-2014 06:19 AM
That worked great, Svetlana! Thank you very much for the help.
I made some slight mods to make it even more portable and intuitive for XSL/XML beginners.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<!-- Replace CHANGEME below with the name of the CPSC Form Dictionary to transform -->
<xsl:variable name="Dictionary">CHANGEME</xsl:variable>
<xsl:template match="root">
<Table>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="1" />
</xsl:call-template>
</Table>
</xsl:template>
<xsl:template name="ProcessOne">
<xsl:param name="pos" />
<xsl:variable name="RowName" select="concat($Dictionary, '-', $pos)" />
<xsl:if test="FormData/*[starts-with(name(), $RowName)] != ''">
<Row>
<xsl:for-each select="FormData/*[starts-with(name(), $RowName)]">
<xsl:if test="starts-with(name(.), $RowName)">
<xsl:variable name="FieldName" select="substring-after(name(.), '.')"/>
<xsl:element name="{$FieldName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</Row>
<xsl:call-template name="ProcessOne">
<xsl:with-param name="pos" select="number($pos+1)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide