cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
820
Views
0
Helpful
2
Replies

CPO XSL Transform for CPSC Form data with Grid

Jason Davis
Cisco Employee
Cisco Employee

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!

 

  

2 Accepted Solutions

Accepted Solutions

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>

View solution in original post

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>

View solution in original post

2 Replies 2

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>

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>

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: