0

I need an xslt transform that would convert an xml generated by one aplication and sent to another application to be processed. Below is a sample source xml containing data field names and their relevant data like 'current_date','item'..for field names and '18-OCT-2018','1044103',.. for data values.

    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <labels _JOBNAME="LBL1273711">
      <label>
        <variable name= "current_date">18-OCT-2018</variable>
        <variable name= "item">1044103</variable>
        <variable name= "item_description">RING,22-16 AWG,#4,RED,PB FREE</variable>
        <variable name= "locator">INRE</variable>
      </label>
    </labels>

The above xml is to transformed as the below xml:

    <XMLScript Version="1.0">
    <Command>
        <Print JobName="LBL1273711">
            <RecordSet Name="Text File 1" Type="btTextFile" AddIfNone="true">
            <TextData><![CDATA[
    current_date", "item", "item_description", "locator"
    "18-OCT-2018", "1044103", "RING,22-16 AWG,#4,RED,PB FREE", "INRE"
                ]]></TextData>
            </RecordSet>
        </Print>
    </Command>
</XMLScript>

The data field names, the field count and their values would vary and change from one incoming xml to another.I'm using the below xslt in one requirement where the field names and the field count are hardcoded. But I need it to be changed to transform the source xml of any number of field count and field names provided in the variable/name.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" cdata-section-elements="TextData"/>
<xsl:template match="/labels">
<XMLScript Version="1.0">
    <Command>
        <Print JobName="{@_JOBNAME}">
            <RecordSet Name="Text File 1" Type="btTextFile" AddIfNone="true">
                <TextData>
                    <xsl:value-of select="concat('&#xa;'
                        ,'current_date','&quot;, &quot;','item','&quot;, &quot;',
                        'item_description','&quot;, &quot;','locator','&quot;&#xa;')" />
                    <xsl:for-each select="label">
                        <xsl:value-of select="concat('&quot;',
                        variable[@name='current_date'],'&quot;, &quot;',
                        variable[@name='item'],'&quot;, &quot;',
                        variable[@name='item_description'],'&quot;, &quot;',
                        variable[@name='locator'],'&quot;&#xa;'
                        )" />
            </xsl:for-each>
                    </TextData>
                </RecordSet>
        </Print>
    </Command>
    </XMLScript>
    </xsl:template>
</xsl:stylesheet>

Thanks in advance.

1 Answer 1

1

If you can assume, for a given XML, each label will have the same variable elements under it, you can do this to output the header....

<xsl:for-each select="label[1]/variable">
   <xsl:if test="position() > 1">,</xsl:if>
  <xsl:value-of select="concat('&quot;', @name, '&quot;')" />
</xsl:for-each>

And similarly, for each label, do this to output the values

<xsl:for-each select="variable">
  <xsl:if test="position() > 1">,</xsl:if>
  <xsl:value-of select="concat('&quot;', ., '&quot;')" />
</xsl:for-each>

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" cdata-section-elements="TextData"/>

<xsl:template match="/labels">
<XMLScript Version="1.0">
  <Command>
    <Print JobName="{@_JOBNAME}">
      <RecordSet Name="Text File 1" Type="btTextFile" AddIfNone="true">
        <TextData>
          <xsl:for-each select="label[1]/variable">
            <xsl:if test="position() > 1">,</xsl:if>
            <xsl:value-of select="concat('&quot;', @name, '&quot;')" />
          </xsl:for-each>
          <xsl:text>&#10;</xsl:text>
          <xsl:for-each select="label">
            <xsl:for-each select="variable">
              <xsl:if test="position() > 1">,</xsl:if>
              <xsl:value-of select="concat('&quot;', ., '&quot;')" />
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
          </xsl:for-each>
        </TextData>
      </RecordSet>
    </Print>
  </Command>
</XMLScript>
</xsl:template>
</xsl:stylesheet>

Note, if you can use XSLT 2.0, you can replace the xsl:for-each with simpler xsl:value-of statements...

<TextData>
  <xsl:value-of select="label[1]/variable/concat('&quot;', @name, '&quot;')" separator="," />
  <xsl:text>&#10;</xsl:text>
  <xsl:for-each select="label">
    <xsl:value-of select="variable/concat('&quot;', ., '&quot;')" separator="," />
    <xsl:text>&#10;</xsl:text>
  </xsl:for-each>
</TextData>
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect. Thank you very much. Thx for the XSLT 2.0 snippet. The application that I use is currently not handling it but I'll keep it and use it when it gets upgraded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.