4

I have a requirement where i need to generate a text file from XML document, generated text file should be in some particular format based on some rules. My XML looks something shown below:

<info>
 <Tag1>
  <Tag2>
   <Tag3>
    <PartNo>12 </PartNo>
   </Tag3>
   <DBOMInf1> 111 </DBOMInf1>
   <DBOMInf2> sring </DBOMInf2>
   </Tag2>
   <Tag2>
    <Tag3>
     <PartNo>12 </PartNo>
    </Tag3>
    <DBOMInf1> 555 </DBOMInf1>
    <DBOMInf2> abcd </DBOMInf2>
   </Tag2>
  </Tag1>
  <Tag4>
   <Tag5>
    <Description>1200 liter </Description>
    <No>12</No>
    <Name>Engine</Name>
    <Id>700</Id>
   </Tag5>
  </Tag4>
  <action>
   <actionId>700</actionId>
  </action>
</info>
  • Expected output format in text:

ACTIONID|NO|DESCRIPTION|NAME|DBOMInf1|DBOMInf2 700|12|Engine|1200 liter| 111|sring 700|12|Engine|1200 liter| 555|abcd

I am new to XSLT programming can any body share some info or example on how can i achieve this , i am familiar with basis of XSLT like templates matching, value of select.

Any link, or example will be very helpful. Thanks

Tim C
  • 70,053
  • 14
  • 74
  • 93
Rajul
  • 41
  • 1
  • 1
  • 4
  • Can you edit your question and elaborate on what "some rules" actually are, as it is not entirely clear from your expected output. It looks like you want a row for each **Tag2** element, with extra information being looked up from the **Tag4** element, but that is just a guessing. – Tim C Jan 10 '12 at 08:52
  • yes you are correct, i have reference format & my output should have value from Tag2 , Tag4 etc arranged in columns as shown. – Rajul Jan 10 '12 at 09:26
  • possible duplicate of [use xsl to output plain text](http://stackoverflow.com/questions/5908668/use-xsl-to-output-plain-text) – givanse Jul 18 '14 at 22:05

1 Answers1

12

It looks like you want a row for each Tag2 element, in which case these are easily matching by doing the following (assuming you are currently positioned on the info element

<xsl:apply-templates select="Tag1/Tag2" />

But it also looks like you want to look up information from Tag5 elements. In this case you could use a key to look up such values, based on the No element. The key would be defined as follows:

<xsl:key name="Tags" match="Tag5" use="No" />

And to look up the tags for a given Tag2 element, you could do the following:

<xsl:apply-templates select="key('Tags', normalize-space(Tag3/PartNo))" />

(Note, normalize-space with remove the excess white-space from the element)

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" indent="yes"/>
   <xsl:key name="Tags" match="Tag5" use="No" />

   <xsl:template match="/info">
      <xsl:text>ACTIONID|NO|DESCRIPTION|NAME|DBOMInf1|DBOMInf2</xsl:text>
      <xsl:value-of select="'&#13;'" />
      <xsl:apply-templates select="Tag1/Tag2" />
   </xsl:template>

   <xsl:template match="Tag2">
      <xsl:apply-templates select="key('Tags', normalize-space(Tag3/PartNo))" />
      <xsl:value-of select="concat(DBOMInf1, '|', DBOMInf2, '&#13;')" />
   </xsl:template>

   <xsl:template match="Tag5">
      <xsl:value-of select="concat(Id, '|', No, '|', Name, '|', Description, '|')" />
   </xsl:template>
</xsl:stylesheet>

When applied to your input XML, the following text is output

ACTIONID|NO|DESCRIPTION|NAME|DBOMInf1|DBOMInf2
700|12|Engine|1200 liter | 111 | sring 
700|12|Engine|1200 liter | 555 | abcd 
Tim C
  • 70,053
  • 14
  • 74
  • 93