Iterate or copy in XSL based on count. How can I do it?

I am trying to create a list of resources (tab delimited text, for output) from XML data. The trick, I need to take the string I created and list it several times (iteration ???) based on the number found in XML. So from the XML below:

<?xml version="1.0" encoding="UTF-8"?> <library> <aisle label="AA"> <row>bb</row> <shelf>a</shelf> <books>4</books> </aisle> <aisle label="BB"> <row>cc</row> <shelf>d</shelf> <books>3</books> </aisle> </library> 

I need to take the value found in the "books" and then copy the text string so many times. The result is as follows:

 Aisle Row Shelf Titles AA bb a AA bb a AA bb a AA bb a BB cc d BB cc d BB cc d 

In this way, the owner of the inventory can then write in the headings found on each shelf. I have the basic structure of my XSL, but I'm not sure how to do the β€œiteration” part.

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0"> <xsl:output omit-xml-declaration="yes"/> <xsl:variable name="tab" select="'&#09;'"/> <xsl:variable name="newline" select="'&#10;'"/> <xsl:template match="/"> <!-- Start Spreadsheet header --> <xsl:text>Aisle</xsl:text> <xsl:value-of select="$tab"/> <xsl:text>Row</xsl:text> <xsl:value-of select="$tab"/> <xsl:text>Shelf</xsl:text> <xsl:value-of select="$tab"/> <xsl:text>Titles</xsl:text> <xsl:value-of select="$newline"/> <!-- End spreadsheet header --> <!-- Start entering values from XML --> <xsl:for-each select="library/aisle"> <xsl:value-of select="@label"/> <xsl:value-of select="$tab"/> <xsl:value-of select="row"/> <xsl:value-of select="$tab"/> <xsl:value-of select="shelf"/> <xsl:value-of select="$tab"/> <xsl:value-of select="$tab"/> <xsl:value-of select="$newline"/> </xsl:for-each> <!-- End of values from XML --> <!-- Iteration of the above needed, based on count value in "books" --> </xsl:template> </xsl:stylesheet> 

Any help would be greatly appreciated. For starters, is β€œiteration” the right term to use for this?

Thanks!

+4
source share
3 answers

And an even simpler non-recursive XSLT 2.0 solution:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" > <xsl:output method="text"/> <xsl:template match="/*"> Aisle Row Shelf Titles&#xA;<xsl:text/> <xsl:apply-templates/> </xsl:template> <xsl:template match="aisle"> <xsl:variable name="vText" select= "concat(@label, '&#9;', row, '&#9;', shelf)" /> <xsl:for-each select="1 to xs:integer(books)"> <xsl:value-of select="concat($vText, '&#xA;')"/> </xsl:for-each> </xsl:template> </xsl:stylesheet> 
+2
source

Here is a simple, recursive XSLT 1.0 solution :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/*"> Aisle Row Shelf Titles&#xA;<xsl:text/> <xsl:apply-templates/> </xsl:template> <xsl:template match="aisle"> <xsl:call-template name="makeRows"> <xsl:with-param name="pText" select="concat(@label, '&#9;', row, '&#9;', shelf)"/> <xsl:with-param name="pNumRows" select="books"/> </xsl:call-template> </xsl:template> <xsl:template name="makeRows"> <xsl:param name="pText"/> <xsl:param name="pNumRows" select="0"/> <xsl:if test="$pNumRows > 0"> <xsl:value-of select="concat($pText, '&#xA;')"/> <xsl:call-template name="makeRows"> <xsl:with-param name="pText" select="$pText"/> <xsl:with-param name="pNumRows" select="$pNumRows -1"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> 

When this conversion is applied to the provided XML document :

 <library> <aisle label="AA"> <row>bb</row> <shelf>a</shelf> <books>4</books> </aisle> <aisle label="BB"> <row>cc</row> <shelf>d</shelf> <books>3</books> </aisle> </library> 

required, the correct result is obtained :

 Aisle Row Shelf Titles AA bb a AA bb a AA bb a AA bb a BB cc d BB cc d BB cc d 
+1
source
 <xsl:param name="pNumRows" select="0"/> 

write <xsl:param name="pNumRows">0</xsl:param>

I think it will work

+1
source

Source: https://habr.com/ru/post/1309596/


All Articles