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
在表中重复打印xml节点_Xml_Xslt_Html Table - Fatal编程技术网

在表中重复打印xml节点

在表中重复打印xml节点,xml,xslt,html-table,Xml,Xslt,Html Table,我有一个xml文件中的数据,它的一个表示是在一个n列表中,作为标签打印。我现在的方式是,每个打印标签对应于xml文件中的一个节点: xml: <?xml version='1.0' encoding='UTF-8'?> <?xml-stylesheet type='text/xsl' href='table.xsl'?> <nodes> <node name="A" /> <node name="

我有一个xml文件中的数据,它的一个表示是在一个n列表中,作为标签打印。我现在的方式是,每个打印标签对应于xml文件中的一个节点:

xml:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='table.xsl'?>
<nodes>
    <node name="A" />
    <node name="A" />
    <node name="A" />
    <node name="B" />
    <node name="B" />
    <node name="B" />
    <node name="B" />
    <node name="C" />
    <node name="C" />
</nodes>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" media-type="text/html" />

<xsl:param name="cols">3</xsl:param> <!-- set the number of columns here -->

<xsl:template match="nodes">
    <table>
        <tr>
        <xsl:apply-templates select="node[position() mod $cols = 1 ]" mode="row"/>
        </tr>
    </table>
</xsl:template>



<xsl:template match="node" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::node[position() &lt; $cols]" mode="cell"/>
    </tr>
</xsl:template>



<xsl:template match="node" mode="cell">
    <td style="border: 1px dotted #999;">
        <xsl:value-of select="./@name"/>    
    </td>
</xsl:template>

</xsl:stylesheet>
A  A  A
B  B  B
B  C  C
<nodes>
    <node name="A" n="3"/>
    <node name="B" n="4"/>
    <node name="C" n="2"/>
</nodes>
为了更好的可维护性和数据完整性,我希望以这样一种方式重新定义xml,即节点不会重复,而是有自己的计数作为属性,因此:

xml:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='table.xsl'?>
<nodes>
    <node name="A" />
    <node name="A" />
    <node name="A" />
    <node name="B" />
    <node name="B" />
    <node name="B" />
    <node name="B" />
    <node name="C" />
    <node name="C" />
</nodes>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" media-type="text/html" />

<xsl:param name="cols">3</xsl:param> <!-- set the number of columns here -->

<xsl:template match="nodes">
    <table>
        <tr>
        <xsl:apply-templates select="node[position() mod $cols = 1 ]" mode="row"/>
        </tr>
    </table>
</xsl:template>



<xsl:template match="node" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::node[position() &lt; $cols]" mode="cell"/>
    </tr>
</xsl:template>



<xsl:template match="node" mode="cell">
    <td style="border: 1px dotted #999;">
        <xsl:value-of select="./@name"/>    
    </td>
</xsl:template>

</xsl:stylesheet>
A  A  A
B  B  B
B  C  C
<nodes>
    <node name="A" n="3"/>
    <node name="B" n="4"/>
    <node name="C" n="2"/>
</nodes>


我的问题是,现在position()不再与打印标签的数量对应。看起来我需要一种I=1到n的
循环。如何实现这一点?

我建议您分两步完成:首先,生成所需的单个单元格;然后将它们组织到表的行中:

XSLT1.0(+EXSLT node-set())


3.

对于XSLT 3,例如使用Saxon JS 2的浏览器内部支持的实例,您可以使用

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:param name="cols" as="xs:integer" select="3"/>
  
  <xsl:function name="mf:repeat" as="item()*">
    <xsl:param name="item" as="item()"/>
    <xsl:param name="count" as="xs:integer"/>
    <xsl:sequence
      select="(1 to $count) ! $item"/>
  </xsl:function>

  <xsl:template match="/">
    <html>
      <head>
        <title>Example</title>
      </head>
      <body>
        <h1>Example</h1>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  
  <xsl:template match="nodes">
    <table>
      <tbody>
        <xsl:for-each-group select="node ! mf:repeat(., @n)" group-adjacent="(position() - 1) idiv $cols">
          <tr>
            <xsl:apply-templates select="current-group()"/>
          </tr>
        </xsl:for-each-group>
      </tbody>
    </table>
  </xsl:template>
  
  <xsl:template match="node">
    <td>{@name}</td>
  </xsl:template>
  
</xsl:stylesheet>

例子
例子
{@name}

声明性语言中没有循环,在XPath 2和更高版本中,您可以与XSLT 2和更高版本一起使用
to
运算符来构造整数序列,例如
1到xs:integer(@n)
。此外,在XSLT3中还有
xsl:iterate
指令。在XSLT1中,通常需要一个命名的递归模板来跟踪“循环”索引。然而,由于您显示的数字很小,您可能只想处理
//node()[position()=current()/@n]
来处理
@n
节点或实现重复
@n
次。这是一个优雅的解决方案,谢谢。事实上,这正是我的想法。但是恐怕我不能用更新的版本。