In XSLT, there is a remove()
function for sequences. Given a sequence and a position, it returns the sequence minus the item at the given position.
The question is: How do I employ this function in an actual XSLT file?
The only place I've found mention of an example that isn't just a regurgitation of the function spec completely devoid of context is here: http://books.google.com/books?id=W6SpffnfEPoC&pg=PA776&lpg=PA776&dq=xslt+%22remove+function%22&source=bl&ots=DQQrnXF_nB&sig=nrJtpEvYjBaZU0K8iAtdPTGUIbI&hl=en&sa=X&ei=QOq8T7aPDOyI6AHh-JBP&ved=0CEQQ6AEwAQ#v=onepage&q=xslt%20%22remove%20function%22&f=false
Unfortunately, the stylesheet examples are on pages 777 and 778, which are, of course, not included. And I don't own that book.
So, does anyone have an example of using the remove()
XSLT function in an actual stylesheet?
Edit: Let's provide a slightly more concrete example, shall we?
I have a sequence in an XSLT. This sequence is comprised of all of the lines from a text file.
<xsl:variable name="lines" select="tokenize(unparsed-text($filePath), '\r?\n')" />
Every one of these lines is a record...except for one, which gives me the record count. So I have the following code for finding that line:
<xsl:variable name="recordCount">
<xsl:for-each select="$lines[position()]">
<xsl:variable name="i" select="position()" />
<xsl:analyze-string select="$lines[$i]" regex="RECORD COUNT = \d+">
<xsl:matching-substring>
<xsl:value-of select="replace($lines[$i], '[^0-9]', '')" />
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
I do the above before I start looping through the lines to get all the actual records, so my goal here is to remove the "RECORD COUNT" line from the $lines
sequence when I find it. That way when I'm looping through grabbing records I don't have to do a check every time asking "Is this actually not a record, but in fact the RECORD COUNT line? You know, that thing I looked for and found already?"
Edit (2): Based on Martin Honnen's answer(s), my final XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!-- I want to produce an XML document. -->
<xsl:output method="xml" indent="yes" />
<!-- Path to input text file. -->
<xsl:param name="filePath" select="TestFile.txt" />
<!-- Regex in replace() removes leading and trailing blank space. -->
<xsl:variable name="text" select="replace(unparsed-text($filePath), '(^[\r\n]*\s*[\r\n]+)|([\r\n]+\s*[\r\n]*$)', '')" />
<!-- Regex in tokenize() sets the delimiter to be any blank space between record lines. -->
<!-- This effectively removes any blank lines. -->
<xsl:variable name="lines" select="tokenize($text, '[\r\n]+\s*[\r\n]*')" />
<!-- This finds the "RECORD COUNT = ?" line. -->
<xsl:variable name="recordCountIndex"
select="for $pos in 1 to count($lines) return $pos[matches($lines[$pos], 'RECORD COUNT = \d+')]" />
<!-- Regex in replace() strips everything that's not a number, leaving only the numeric count. -->
<!-- Example: "RECORD COUNT = 25" -> "25" -->
<xsl:variable name="recordCount" select="replace($lines[$recordCountIndex], '[^0-9]', '')" />
<xsl:template name="main">
<root>
<recordCount>
<!-- The record count value being inserted. -->
<xsl:value-of select="$recordCount" />
</recordCount>
<records>
<!-- Iterate over the $lines minus the line containing the record count. -->
<xsl:for-each select="remove($lines, $recordCountIndex)">
<!-- Items in each record, split by blank space. -->
<!-- Example: "a b c" -> "[a, b, c]" -->
<xsl:variable name="record" select="tokenize(., ' ')[position()]" />
<record>
<aThing>
<xsl:value-of select="$record[1]" />
</aThing>
<aDifferentThing>
<xsl:value-of select="$record[2]" />
</aDifferentThing>
<someStuff>
<xsl:value-of select="$record[3]" />
</someStuff>
</record>
</xsl:for-each>
</records>
</root>
</xsl:template>
</xsl:stylesheet>