6

I am trying to use increment in XSLT. and write the output to txt file. Here's my code: Xslt code:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="text"/>
    <xsl:result-document href="foo.txt" method=text />
    <xsl:template match="/">
    </xsl:template>

  <xsl:template match="/build/build">
    <xsl:variable name="buildNumber" select="."/>
    <xsl:element name="build">
      <xsl:value-of select="$buildNumber + 1"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="/|@*|node()">
    <xsl:value-of select="build/major"/>
    <xsl:value-of select="build/minor"/>
    <xsl:value-of select="build/build"/>
    <xsl:value-of select="build/release"/>
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>  
  </xsl:template>
</xsl:stylesheet>

XML code is:

 <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet type="text/xsl" href="E:\Build\genVer.xsl"?>
    <build>
        <major>1.</major><minor>0.</minor><build>0</build><release>.0</release>
    </build>

I tried using <xsl:result-document> it gives error saying <xsl:result-document> cannot be child of <xsl:stylesheet> or <xsl:template>. Thankyou

Rizwana Khan
  • 101
  • 1
  • 1
  • 9
  • 2
    XSLT is a functional language, and as a result variables are 'immutable' meaning once set, they cannot be changed. But don't panic, this is far from being a hindrance. You just need to approach your problem in a different way. If you can amend your question to explain what you are trying to achieve (ideally with a slightly larger input XML sample, and your expected output), then we should be able to point you in the right direction. Thanks! – Tim C Mar 29 '13 at 16:13
  • So, what is the exact wanted result (please, edit the question and provide this) and what are the rules/constraints the transformation must implement (again, please, edit the question and provide this) ? – Dimitre Novatchev Mar 30 '13 at 04:18
  • Just use the command-line utility of any XSLT processor -- it allows to specify the output file. – Dimitre Novatchev Mar 30 '13 at 04:20
  • i am writing Nant script to automate the build. Result - i want , everytime i run a build, the version number should increase. for ex: if current version is 1.0.0.0 the next autogenetrated version should be something like this 1.0.1.0, 1.0.2.0...and then write to an output file. I also want to use this version number as my destination folder name. where i will copy my .dll's – Rizwana Khan Apr 01 '13 at 17:57

2 Answers2

10

Your approach with <xsl:result-document> is perfectly sound. The only problem is that your stylesheet is XSLT 1, and for <xsl:result-document> you need XSLT 2. XSLT being a functional language has nothing to do with this problem.

If necessary, post your XSLT code that uses <xsl:result-document> and I'll fix it for you.

Edit:

Here your code with the necessary changes. Parts of your original code such as method="text" indicate you want the result to be a text file, while <xsl:element> looks like you're trying to output an XML file, so I wrote code for both. As mentioned before, <xsl:result-document> requires XSLT 2.

This creates an XML file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml"/>

   <xsl:template match="/">
      <xsl:variable name="foldername" select="concat(/build/major, /build/minor, string(/build/build + 1), build/release)"/>
      <xsl:result-document href="{$foldername}/foo.xml" method="xml">
         <xsl:copy>
            <xsl:apply-templates/>
         </xsl:copy>
      </xsl:result-document>
   </xsl:template>

   <xsl:template match="element()">
      <xsl:copy>
         <xsl:apply-templates/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="/build/build">
      <xsl:copy>
         <xsl:variable name="buildNumber" select="."/>
         <xsl:value-of select="$buildNumber + 1"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

And this creates a text file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text"/>

   <xsl:template match="/">
      <xsl:variable name="foldername" select="concat(/build/major, /build/minor, string(/build/build + 1), build/release)"/>
      <xsl:result-document href="{$foldername}/foo.txt" method="text">
         <xsl:apply-templates/>
      </xsl:result-document>
   </xsl:template>

   <xsl:template match="element()">
      <xsl:apply-templates/>
   </xsl:template>

   <xsl:template match="/build/build">
      <xsl:variable name="buildNumber" select="."/>
      <xsl:value-of select="$buildNumber + 1"/>
   </xsl:template>

</xsl:stylesheet>

The output file is created in a folder whose name is the version, as you wanted, but note the folder must exist beforehand.

Dabbler
  • 9,733
  • 5
  • 41
  • 64
  • Thanx for the reply. i used the the code which results in text. but it gives me the following error:XslTransformException was unhandled by user code - 'result-document' is not a recognized extension element. An error occurred at E:\Build\genVer.xsl(7,6). i have used xslt=2 as mentioned. – Rizwana Khan Apr 05 '13 at 21:19
0

In my environment XSLT 2.0 is not supported, so I came up with the following workaround:

#!/usr/bin/zsh

. =(xsltproc =(<<'XSLT_'
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text"/>
   <xsl:strip-space elements="*"/>

<xsl:template match="/SummitFTMonitor/messages">
  <xsl:variable name="key" select="Key/text()"/>

<![CDATA[cat <<'IJEBVNKCEUJGHKLO' > ]]><xsl:value-of select="$key"/>_response.xml
<xsl:value-of select="Response"/>
IJEBVNKCEUJGHKLO

</xsl:template>
</xsl:stylesheet>
XSLT_) $*)

Basically, in this zsh script XSLT is used to produce statements like

cat <<'XXXXX' > file_name
the value of nodes, etc ....
XXXXX

These statements are then sourced by zsh, resulting in files being created.

Alex J.
  • 86
  • 3