我正在尝试从XML数据创建清单列表(以制表符分隔的文本,用于输出)。问题是,我需要采用我创建的行,并根据XML中的数字列出多次(迭代???)。所以,从下面的XML:
<?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>
我需要获取“books”中的值,然后复制文本行数次。结果如下:
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
然后,库存接受者可以写入每个货架上的标题。我有我的XSL的基本结构,但我不知道如何做“迭代”部分。
<?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="'	'"/>
<xsl:variable name="newline" select="' '"/>
<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>
非常感谢任何帮助。对于初学者来说,“迭代”是否适合用于此目的?
谢谢!
答案 0 :(得分:2)
更简单的XSLT 2.0非递归解决方案:
<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
<xsl:text/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="aisle">
<xsl:variable name="vText" select=
"concat(@label, '	', row, '	', shelf)"
/>
<xsl:for-each select="1 to xs:integer(books)">
<xsl:value-of select="concat($vText, '
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
这是一个简单的递归XSLT 1.0解决方案:
<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
<xsl:text/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="aisle">
<xsl:call-template name="makeRows">
<xsl:with-param name="pText"
select="concat(@label, '	', row, '	', 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, '
')"/>
<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>
在提供的XML文档上应用此转换时:
<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>
产生了想要的正确结果:
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
答案 2 :(得分:1)
<xsl:param name="pNumRows" select="0"/>
写下<xsl:param name="pNumRows">0</xsl:param>
我认为它会起作用