Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用XSLT1.0来填补XML列表中的漏洞?_Xml_Xslt_Xslt 1.0 - Fatal编程技术网

如何使用XSLT1.0来填补XML列表中的漏洞?

如何使用XSLT1.0来填补XML列表中的漏洞?,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我有一个要在HTML表中显示的项目列表。但是,列表中有一些“漏洞”,需要填写才能正确显示(表中的列和行是x和y)。我甚至不知道从哪里开始做这件事 <items> <row y="1"> <item x="1" y="1" data="importantStuff1"/> </row> <row y="2"> <item x="2" y="2" data="importantStuff3"/>

我有一个要在HTML表中显示的项目列表。但是,列表中有一些“漏洞”,需要填写才能正确显示(表中的列和行是
x
y
)。我甚至不知道从哪里开始做这件事

<items>
  <row y="1">
    <item x="1" y="1" data="importantStuff1"/>
  </row>
  <row y="2">
    <item x="2" y="2" data="importantStuff3"/>
  </row>
  <row y="3">
    <item x="5" y="3" data="importantStuff1"/>
  </row>
  <row y="4">
    <item x="3" y="4" data="importantStuff2"/>
    <item x="4" y="4" data="importantStuff3"/>
  </row>
</items>

我需要的是:

<items>
  <row y="1">
    <item x="1" y="1" data="importantStuff1"/>
    <item x="2" y="1" data="padding"/>
    <item x="3" y="1" data="padding"/>
    <item x="4" y="1" data="padding"/>
    <item x="5" y="1" data="padding"/>
  </row>
  <row y="2">
    <item x="1" y="2" data="padding"/>
    <item x="2" y="2" data="importantStuff3"/>
    <item x="3" y="2" data="padding"/>
    <item x="4" y="2" data="padding"/>
    <item x="5" y="2" data="padding"/>
  </row>
  <row y="3">
    <item x="1" y="3" data="padding"/>
    <item x="2" y="3" data="padding"/>
    <item x="3" y="3" data="padding"/>
    <item x="4" y="3" data="padding"/>
    <item x="5" y="3" data="importantStuff1"/>
  </row>
  <row y="4">
    <item x="1" y="4" data="padding"/>
    <item x="2" y="4" data="padding"/>
    <item x="3" y="4" data="importantStuff2"/>
    <item x="4" y="4" data="importantStuff3"/>
    <item x="5" y="4" data="padding"/>
  </row>
</items>

如何将列表填充成这样?这些物品保证会被订购,我知道每个轴上有多少物品

编辑:我不知道这个问题可以解释为我想要一个简单的列表。每个项中都有额外的数据,因此保留现有项节点非常重要。所以我需要的是一种只创建填充节点并保持现有节点不变的方法


为了创建一个最小的示例来演示我的问题,我有点过火了。对此很抱歉。

您可以通过以下XSLT实现这一点。这是一种特殊的解决方案,但是通过使用带名称空间的XML岛来创建“count”变量对于模拟具有固定计数的“for”循环来说是一种非常通用的方法

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cnt="http://cnt.com" exclude-result-prefixes="cnt">
  <xsl:output method="xml" indent="yes" />

  <!-- creating a "count" XML structure -->
  <cnt:count>
    <x cnt="1" />
    <x cnt="2" />
    <x cnt="3" />
    <x cnt="4" />
    <x cnt="5" />
  </cnt:count>

  <xsl:template match="items">
    <items>
      <xsl:for-each select="row">
        <xsl:variable name="varY" select="@y" />   <!-- saving the value of '@y' -->
        <row y="{$varY}">
          <xsl:for-each select="document('')/xsl:stylesheet/cnt:count/x">
            <item x="{@cnt}" y="{$varY}" />
          </xsl:for-each>      
        </row>
      </xsl:for-each>      
    </items>
  </xsl:template>

</xsl:stylesheet>


输出符合要求。

您可以使用以下XSLT实现这一点。这是一种特殊的解决方案,但是通过使用带名称空间的XML岛来创建“count”变量对于模拟具有固定计数的“for”循环来说是一种非常通用的方法

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cnt="http://cnt.com" exclude-result-prefixes="cnt">
  <xsl:output method="xml" indent="yes" />

  <!-- creating a "count" XML structure -->
  <cnt:count>
    <x cnt="1" />
    <x cnt="2" />
    <x cnt="3" />
    <x cnt="4" />
    <x cnt="5" />
  </cnt:count>

  <xsl:template match="items">
    <items>
      <xsl:for-each select="row">
        <xsl:variable name="varY" select="@y" />   <!-- saving the value of '@y' -->
        <row y="{$varY}">
          <xsl:for-each select="document('')/xsl:stylesheet/cnt:count/x">
            <item x="{@cnt}" y="{$varY}" />
          </xsl:for-each>      
        </row>
      </xsl:for-each>      
    </items>
  </xsl:template>

</xsl:stylesheet>


输出符合要求。

如果您的示例与实际数据一样简单,您应该能够使用递归模板调用来检查这5项中的每一项。如果有,则对其应用模板。如果不是,就创建它

例如

XML输入

<items>
    <row y="1">
        <item x="1" y="1" data="importantStuff1"/>
    </row>
    <row y="2">
        <item x="2" y="2" data="importantStuff3"/>
    </row>
    <row y="3">
        <item x="5" y="3" data="importantStuff1"/>
    </row>
    <row y="4">
        <item x="3" y="4" data="importantStuff2"/>
        <item x="4" y="4" data="importantStuff3"/>
    </row>5
</items>
<items>
   <row y="1">
      <item x="1" y="1" data="importantStuff1"/>
      <item x="2" y="1" data="padding"/>
      <item x="3" y="1" data="padding"/>
      <item x="4" y="1" data="padding"/>
      <item x="5" y="1" data="padding"/>
   </row>
   <row y="2">
      <item x="1" y="2" data="padding"/>
      <item x="2" y="2" data="importantStuff3"/>
      <item x="3" y="2" data="padding"/>
      <item x="4" y="2" data="padding"/>
      <item x="5" y="2" data="padding"/>
   </row>
   <row y="3">
      <item x="1" y="3" data="padding"/>
      <item x="2" y="3" data="padding"/>
      <item x="3" y="3" data="padding"/>
      <item x="4" y="3" data="padding"/>
      <item x="5" y="3" data="importantStuff1"/>
   </row>
   <row y="4">
      <item x="1" y="4" data="padding"/>
      <item x="2" y="4" data="padding"/>
      <item x="3" y="4" data="importantStuff2"/>
      <item x="4" y="4" data="importantStuff3"/>
      <item x="5" y="4" data="padding"/>
   </row>5
</items>

5.
XSLT1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="items" select="5"/>

  <!--Identity transform. Copy everything as-is unless overridden by
  a more specific template.--> 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="row">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="1"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="outputItems">
    <xsl:param name="count"/>
    <xsl:choose>
      <!--Item already exists.-->
      <xsl:when test="item[@x=$count]">
        <xsl:apply-templates select="item[@x=$count]"/>
      </xsl:when>
      <!--Item does not exist. create it.-->
      <xsl:otherwise>
        <item x="{$count}" y="{@y}" data="padding"/>
      </xsl:otherwise>
    </xsl:choose>
    <!--Call this template again if needed.-->
    <xsl:if test="$items > $count">
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="$count + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

<xsl:key name="item" match="item" use="concat(@x, '|', @y)" />

<xsl:template match="/items">
    <xsl:copy>
        <xsl:call-template name="generate-rows"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="y" select="1"/>
    <xsl:if test="$y &lt;= $rows">
        <row y="{$y}">
            <xsl:call-template name="generate-cols">
                <xsl:with-param name="y" select="$y"/>
            </xsl:call-template>
        </row>
        <!-- recursive call -->
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="y" select="$y + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="generate-cols">
    <xsl:param name="y"/>
    <xsl:param name="x" select="1"/>
    <xsl:if test="$x &lt;= $cols">
         <item x="{$x}" y="{$y}" >
            <xsl:variable name="exisiting-item" select="key('item', concat($x, '|', $y))" />
            <xsl:attribute name="data">
                <xsl:choose>
                    <xsl:when test="$exisiting-item">
                        <xsl:value-of select="$exisiting-item/@data"/>
                    </xsl:when>
                    <xsl:otherwise>padding</xsl:otherwise>
                </xsl:choose>
            </xsl:attribute>
        </item>
        <!-- recursive call -->
        <xsl:call-template name="generate-cols">
            <xsl:with-param name="y" select="$y"/>
            <xsl:with-param name="x" select="$x + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

输出

<items>
    <row y="1">
        <item x="1" y="1" data="importantStuff1"/>
    </row>
    <row y="2">
        <item x="2" y="2" data="importantStuff3"/>
    </row>
    <row y="3">
        <item x="5" y="3" data="importantStuff1"/>
    </row>
    <row y="4">
        <item x="3" y="4" data="importantStuff2"/>
        <item x="4" y="4" data="importantStuff3"/>
    </row>5
</items>
<items>
   <row y="1">
      <item x="1" y="1" data="importantStuff1"/>
      <item x="2" y="1" data="padding"/>
      <item x="3" y="1" data="padding"/>
      <item x="4" y="1" data="padding"/>
      <item x="5" y="1" data="padding"/>
   </row>
   <row y="2">
      <item x="1" y="2" data="padding"/>
      <item x="2" y="2" data="importantStuff3"/>
      <item x="3" y="2" data="padding"/>
      <item x="4" y="2" data="padding"/>
      <item x="5" y="2" data="padding"/>
   </row>
   <row y="3">
      <item x="1" y="3" data="padding"/>
      <item x="2" y="3" data="padding"/>
      <item x="3" y="3" data="padding"/>
      <item x="4" y="3" data="padding"/>
      <item x="5" y="3" data="importantStuff1"/>
   </row>
   <row y="4">
      <item x="1" y="4" data="padding"/>
      <item x="2" y="4" data="padding"/>
      <item x="3" y="4" data="importantStuff2"/>
      <item x="4" y="4" data="importantStuff3"/>
      <item x="5" y="4" data="padding"/>
   </row>5
</items>

5.

如果您的示例与实际数据一样简单,您应该能够使用递归模板调用来检查这5项中的每一项。如果有,则对其应用模板。如果不是,就创建它

例如

XML输入

<items>
    <row y="1">
        <item x="1" y="1" data="importantStuff1"/>
    </row>
    <row y="2">
        <item x="2" y="2" data="importantStuff3"/>
    </row>
    <row y="3">
        <item x="5" y="3" data="importantStuff1"/>
    </row>
    <row y="4">
        <item x="3" y="4" data="importantStuff2"/>
        <item x="4" y="4" data="importantStuff3"/>
    </row>5
</items>
<items>
   <row y="1">
      <item x="1" y="1" data="importantStuff1"/>
      <item x="2" y="1" data="padding"/>
      <item x="3" y="1" data="padding"/>
      <item x="4" y="1" data="padding"/>
      <item x="5" y="1" data="padding"/>
   </row>
   <row y="2">
      <item x="1" y="2" data="padding"/>
      <item x="2" y="2" data="importantStuff3"/>
      <item x="3" y="2" data="padding"/>
      <item x="4" y="2" data="padding"/>
      <item x="5" y="2" data="padding"/>
   </row>
   <row y="3">
      <item x="1" y="3" data="padding"/>
      <item x="2" y="3" data="padding"/>
      <item x="3" y="3" data="padding"/>
      <item x="4" y="3" data="padding"/>
      <item x="5" y="3" data="importantStuff1"/>
   </row>
   <row y="4">
      <item x="1" y="4" data="padding"/>
      <item x="2" y="4" data="padding"/>
      <item x="3" y="4" data="importantStuff2"/>
      <item x="4" y="4" data="importantStuff3"/>
      <item x="5" y="4" data="padding"/>
   </row>5
</items>

5.
XSLT1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="items" select="5"/>

  <!--Identity transform. Copy everything as-is unless overridden by
  a more specific template.--> 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="row">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="1"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="outputItems">
    <xsl:param name="count"/>
    <xsl:choose>
      <!--Item already exists.-->
      <xsl:when test="item[@x=$count]">
        <xsl:apply-templates select="item[@x=$count]"/>
      </xsl:when>
      <!--Item does not exist. create it.-->
      <xsl:otherwise>
        <item x="{$count}" y="{@y}" data="padding"/>
      </xsl:otherwise>
    </xsl:choose>
    <!--Call this template again if needed.-->
    <xsl:if test="$items > $count">
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="$count + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

<xsl:key name="item" match="item" use="concat(@x, '|', @y)" />

<xsl:template match="/items">
    <xsl:copy>
        <xsl:call-template name="generate-rows"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="y" select="1"/>
    <xsl:if test="$y &lt;= $rows">
        <row y="{$y}">
            <xsl:call-template name="generate-cols">
                <xsl:with-param name="y" select="$y"/>
            </xsl:call-template>
        </row>
        <!-- recursive call -->
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="y" select="$y + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="generate-cols">
    <xsl:param name="y"/>
    <xsl:param name="x" select="1"/>
    <xsl:if test="$x &lt;= $cols">
         <item x="{$x}" y="{$y}" >
            <xsl:variable name="exisiting-item" select="key('item', concat($x, '|', $y))" />
            <xsl:attribute name="data">
                <xsl:choose>
                    <xsl:when test="$exisiting-item">
                        <xsl:value-of select="$exisiting-item/@data"/>
                    </xsl:when>
                    <xsl:otherwise>padding</xsl:otherwise>
                </xsl:choose>
            </xsl:attribute>
        </item>
        <!-- recursive call -->
        <xsl:call-template name="generate-cols">
            <xsl:with-param name="y" select="$y"/>
            <xsl:with-param name="x" select="$x + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

输出

<items>
    <row y="1">
        <item x="1" y="1" data="importantStuff1"/>
    </row>
    <row y="2">
        <item x="2" y="2" data="importantStuff3"/>
    </row>
    <row y="3">
        <item x="5" y="3" data="importantStuff1"/>
    </row>
    <row y="4">
        <item x="3" y="4" data="importantStuff2"/>
        <item x="4" y="4" data="importantStuff3"/>
    </row>5
</items>
<items>
   <row y="1">
      <item x="1" y="1" data="importantStuff1"/>
      <item x="2" y="1" data="padding"/>
      <item x="3" y="1" data="padding"/>
      <item x="4" y="1" data="padding"/>
      <item x="5" y="1" data="padding"/>
   </row>
   <row y="2">
      <item x="1" y="2" data="padding"/>
      <item x="2" y="2" data="importantStuff3"/>
      <item x="3" y="2" data="padding"/>
      <item x="4" y="2" data="padding"/>
      <item x="5" y="2" data="padding"/>
   </row>
   <row y="3">
      <item x="1" y="3" data="padding"/>
      <item x="2" y="3" data="padding"/>
      <item x="3" y="3" data="padding"/>
      <item x="4" y="3" data="padding"/>
      <item x="5" y="3" data="importantStuff1"/>
   </row>
   <row y="4">
      <item x="1" y="4" data="padding"/>
      <item x="2" y="4" data="padding"/>
      <item x="3" y="4" data="importantStuff2"/>
      <item x="4" y="4" data="importantStuff3"/>
      <item x="5" y="4" data="padding"/>
   </row>5
</items>

5.
我知道每个轴上有多少个项目

假设您可以将这些知识作为参数传递给样式表,我建议您这样做:

XSLT1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="items" select="5"/>

  <!--Identity transform. Copy everything as-is unless overridden by
  a more specific template.--> 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="row">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="1"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="outputItems">
    <xsl:param name="count"/>
    <xsl:choose>
      <!--Item already exists.-->
      <xsl:when test="item[@x=$count]">
        <xsl:apply-templates select="item[@x=$count]"/>
      </xsl:when>
      <!--Item does not exist. create it.-->
      <xsl:otherwise>
        <item x="{$count}" y="{@y}" data="padding"/>
      </xsl:otherwise>
    </xsl:choose>
    <!--Call this template again if needed.-->
    <xsl:if test="$items > $count">
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="$count + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

<xsl:key name="item" match="item" use="concat(@x, '|', @y)" />

<xsl:template match="/items">
    <xsl:copy>
        <xsl:call-template name="generate-rows"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="y" select="1"/>
    <xsl:if test="$y &lt;= $rows">
        <row y="{$y}">
            <xsl:call-template name="generate-cols">
                <xsl:with-param name="y" select="$y"/>
            </xsl:call-template>
        </row>
        <!-- recursive call -->
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="y" select="$y + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="generate-cols">
    <xsl:param name="y"/>
    <xsl:param name="x" select="1"/>
    <xsl:if test="$x &lt;= $cols">
         <item x="{$x}" y="{$y}" >
            <xsl:variable name="exisiting-item" select="key('item', concat($x, '|', $y))" />
            <xsl:attribute name="data">
                <xsl:choose>
                    <xsl:when test="$exisiting-item">
                        <xsl:value-of select="$exisiting-item/@data"/>
                    </xsl:when>
                    <xsl:otherwise>padding</xsl:otherwise>
                </xsl:choose>
            </xsl:attribute>
        </item>
        <!-- recursive call -->
        <xsl:call-template name="generate-cols">
            <xsl:with-param name="y" select="$y"/>
            <xsl:with-param name="x" select="$x + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

衬垫
这将预生成所提供维度的表格,并用相应项(如果存在)的数据填充每个单元格

--

补充: 如果需要从输入推导出表格尺寸,则更改:

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

致:


这将最后一行的
y
值和任何项目的最大
x
值作为表维度

我知道每个轴上有多少个项目

假设您可以将这些知识作为参数传递给样式表,我建议您这样做:

XSLT1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="items" select="5"/>

  <!--Identity transform. Copy everything as-is unless overridden by
  a more specific template.--> 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="row">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="1"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="outputItems">
    <xsl:param name="count"/>
    <xsl:choose>
      <!--Item already exists.-->
      <xsl:when test="item[@x=$count]">
        <xsl:apply-templates select="item[@x=$count]"/>
      </xsl:when>
      <!--Item does not exist. create it.-->
      <xsl:otherwise>
        <item x="{$count}" y="{@y}" data="padding"/>
      </xsl:otherwise>
    </xsl:choose>
    <!--Call this template again if needed.-->
    <xsl:if test="$items > $count">
      <xsl:call-template name="outputItems">
        <xsl:with-param name="count" select="$count + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

<xsl:key name="item" match="item" use="concat(@x, '|', @y)" />

<xsl:template match="/items">
    <xsl:copy>
        <xsl:call-template name="generate-rows"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="y" select="1"/>
    <xsl:if test="$y &lt;= $rows">
        <row y="{$y}">
            <xsl:call-template name="generate-cols">
                <xsl:with-param name="y" select="$y"/>
            </xsl:call-template>
        </row>
        <!-- recursive call -->
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="y" select="$y + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="generate-cols">
    <xsl:param name="y"/>
    <xsl:param name="x" select="1"/>
    <xsl:if test="$x &lt;= $cols">
         <item x="{$x}" y="{$y}" >
            <xsl:variable name="exisiting-item" select="key('item', concat($x, '|', $y))" />
            <xsl:attribute name="data">
                <xsl:choose>
                    <xsl:when test="$exisiting-item">
                        <xsl:value-of select="$exisiting-item/@data"/>
                    </xsl:when>
                    <xsl:otherwise>padding</xsl:otherwise>
                </xsl:choose>
            </xsl:attribute>
        </item>
        <!-- recursive call -->
        <xsl:call-template name="generate-cols">
            <xsl:with-param name="y" select="$y"/>
            <xsl:with-param name="x" select="$x + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

衬垫
这将预生成所提供维度的表格,并用相应项(如果存在)的数据填充每个单元格

--

补充: 如果需要从输入推导出表格尺寸,则更改:

<xsl:param name="rows" select="4"/>
<xsl:param name="cols" select="5"/>

致:



这将最后一行的
y
值和任何项的最大
x
值作为表维度。

可能的重复项使用这些技术来构建完整的表,并根据循环索引从输入XML中选择适当的数据。您需要澄清如何准确地“知道每个轴上有多少个项目”和