Xml XSLT递归应用模板不起作用
我计划递归地应用一个模板来扫描输入XML中的所有项目(行和列) 以下是输入xml:Xml XSLT递归应用模板不起作用,xml,xslt,Xml,Xslt,我计划递归地应用一个模板来扫描输入XML中的所有项目(行和列) 以下是输入xml: <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <layout class="QGridLayout" name="gridLayout_2"> <item row="1"
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1" colspan="3">
</item>
<item row="1" column="3">
</item>
<item row="0" column="1">
</item>
</layout>
</ui>
(1,3)对于maxR和maxC是正确的。然而,我预计
(1,3)
[0,0] [0,1] [0,2]
我不知道怎么了?$curC+1似乎不起作用?似乎您遗漏了一些行来复制上面的xslt代码。将以下代码视为您当前的xslt代码
<?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="#all"
version="3.0">
<xsl:variable name="maxR" select="xs:integer(max(//layout/item/@row))" as="xs:integer"/>
<xsl:variable name="maxC" select="xs:integer(max(//layout/item/@column))" as="xs:integer"/>
<xsl:template match="/ui">
(<xsl:value-of select="$maxR"/>,<xsl:value-of select="$maxC"/>)
<ul>
<xsl:apply-templates select="layout/item">
<xsl:with-param name="curR" select="0"/>
<xsl:with-param name="curC" select="0"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:apply-templates>
</ul>
</xsl:template>
<!-- ********************** Template ********************** -->
<xsl:template name="grpBxRC" match="layout/item">
<xsl:param name="curR" as="xs:integer"/>
<xsl:param name="curC" as="xs:integer"/>
<xsl:param name="maxR" as="xs:integer"/>
<xsl:param name="maxC" as="xs:integer"/>
[<xsl:value-of select="$curR"/>,<xsl:value-of select="$curC"/>]
<xsl:if test="$maxC > $curC">
<xsl:apply-templates select="layout/item">
<xsl:with-param name="curR" select="$curR"/>
<xsl:with-param name="curC" select="$curC + 1"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
为了实现预期的结果,如果您有特定的要求坚持使用动态列,则可以采用以下方法:
<?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="#all"
version="3.0">
<xsl:variable name="maxR" select="xs:integer(max(//layout/item/@row))" as="xs:integer"/>
<xsl:variable name="maxC" select="xs:integer(max(//layout/item/@column))" as="xs:integer"/>
<xsl:template match="/ui">
(<xsl:value-of select="$maxR"/>,<xsl:value-of select="$maxC"/>)
<xsl:call-template name="grpBxRC">
<xsl:with-param name="node" select="layout/item"/>
<xsl:with-param name="curR" select="0"/>
<xsl:with-param name="curC" select="0"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="grpBxRC">
<xsl:param name="node"/>
<xsl:param name="curR" as="xs:integer"/>
<xsl:param name="curC" as="xs:integer"/>
<xsl:param name="maxR" as="xs:integer"/>
<xsl:param name="maxC" as="xs:integer"/>
<xsl:if test="$maxC > $curC">
[<xsl:value-of select="$curR"/>,<xsl:value-of select="$curC"/>]
<xsl:call-template name="grpBxRC">
<xsl:with-param name="node"/>
<xsl:with-param name="curR" select="$curR"/>
<xsl:with-param name="curC" select="$curC + 1"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
(,)
[,]
但是,如果您想动态增加行和列,可以使用以下解决方案:
<?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="#all"
version="3.0">
<xsl:variable name="maxR" select="xs:integer(max(//layout/item/@row))" as="xs:integer"/>
<xsl:variable name="maxC" select="xs:integer(max(//layout/item/@column))" as="xs:integer"/>
<xsl:template match="/ui">
(<xsl:value-of select="$maxR"/>,<xsl:value-of select="$maxC"/>)
<xsl:call-template name="iterate-row">
<xsl:with-param name="row" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="iterate-row">
<xsl:param name="row"/>
<xsl:if test="$maxR > $row">
<xsl:call-template name="iterate-column">
<xsl:with-param name="row" select="$row"/>
<xsl:with-param name="col" select="0"/>
</xsl:call-template>
<xsl:call-template name="iterate-row">
<xsl:with-param name="row" select="$row + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="iterate-column">
<xsl:param name="col"/>
<xsl:param name="row"/>
<xsl:if test="$maxC > $col ">
[<xsl:value-of select="$row"/>,<xsl:value-of select="$col"/>]
<xsl:call-template name="iterate-column">
<xsl:with-param name="col" select="$col + 1"/>
<xsl:with-param name="row" select="$row"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
(,)
[,]
为了让我们能够轻松理解和重现问题,请提供最小但完整的XML输入。您没有嵌套的布局/项目
元素,因此如果应用模板
使用该路径,您希望在何处发生递归。使用第一个apply-templates处理的是一个平面结构。了解您试图实现的内容的语义会有所帮助。您的代码显然是错误的,但是如果不知道它试图做什么,就很难纠正它。
<!-- ********************** Template ********************** -->
<xsl:template name="grpBxRC" match="layout/item">
<xsl:param name="curR" as="xs:integer"/>
<xsl:param name="curC" as="xs:integer"/>
<xsl:param name="maxR" as="xs:integer"/>
<xsl:param name="maxC" as="xs:integer"/>
<xsl:if test="$maxC > $curC">
[<xsl:value-of select="$curR"/>,<xsl:value-of select="$curC"/>]
<xsl:call-template name="grpBxRC">
<xsl:with-param name="curR" select="$curR"/>
<xsl:with-param name="curC" select="$curC + 1"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<?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="#all"
version="3.0">
<xsl:variable name="maxR" select="xs:integer(max(//layout/item/@row))" as="xs:integer"/>
<xsl:variable name="maxC" select="xs:integer(max(//layout/item/@column))" as="xs:integer"/>
<xsl:template match="/ui">
(<xsl:value-of select="$maxR"/>,<xsl:value-of select="$maxC"/>)
<xsl:call-template name="grpBxRC">
<xsl:with-param name="node" select="layout/item"/>
<xsl:with-param name="curR" select="0"/>
<xsl:with-param name="curC" select="0"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="grpBxRC">
<xsl:param name="node"/>
<xsl:param name="curR" as="xs:integer"/>
<xsl:param name="curC" as="xs:integer"/>
<xsl:param name="maxR" as="xs:integer"/>
<xsl:param name="maxC" as="xs:integer"/>
<xsl:if test="$maxC > $curC">
[<xsl:value-of select="$curR"/>,<xsl:value-of select="$curC"/>]
<xsl:call-template name="grpBxRC">
<xsl:with-param name="node"/>
<xsl:with-param name="curR" select="$curR"/>
<xsl:with-param name="curC" select="$curC + 1"/>
<xsl:with-param name="maxR" select="$maxR"/>
<xsl:with-param name="maxC" select="$maxC"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?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="#all"
version="3.0">
<xsl:variable name="maxR" select="xs:integer(max(//layout/item/@row))" as="xs:integer"/>
<xsl:variable name="maxC" select="xs:integer(max(//layout/item/@column))" as="xs:integer"/>
<xsl:template match="/ui">
(<xsl:value-of select="$maxR"/>,<xsl:value-of select="$maxC"/>)
<xsl:call-template name="iterate-row">
<xsl:with-param name="row" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="iterate-row">
<xsl:param name="row"/>
<xsl:if test="$maxR > $row">
<xsl:call-template name="iterate-column">
<xsl:with-param name="row" select="$row"/>
<xsl:with-param name="col" select="0"/>
</xsl:call-template>
<xsl:call-template name="iterate-row">
<xsl:with-param name="row" select="$row + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="iterate-column">
<xsl:param name="col"/>
<xsl:param name="row"/>
<xsl:if test="$maxC > $col ">
[<xsl:value-of select="$row"/>,<xsl:value-of select="$col"/>]
<xsl:call-template name="iterate-column">
<xsl:with-param name="col" select="$col + 1"/>
<xsl:with-param name="row" select="$row"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>