创建一个表瓦特/ XSLT 1.0连接多个值(Create A Table w/ XSLT 1.0

2019-09-26 12:42发布

所以,我需要创建一个使用XSLT 1.0动态表。 我看了几篇文章/文章,但我似乎不能把它放在一起。 在许多情况下,会有好几个表格单元格数据为空。 在其他情况下,就会出现需要连接成一个单元的多个值。 下面是示例XML:

<Document>
<Records>
  <User>
    <Name>User1</Name>
    <list xid="data.set">
      <Data>
        <Column>2</Column>
        <Type>Carbs</Type>
        <RowValue>Oatmeal</RowValue>
      </Data>
      <Data>
        <Column>1</Column>
        <Type>Protein</Type>
        <RowValue>sausage</RowValue>
        <RowValue>eggs</RowValue>
        <RowValue>turkey</RowValue>
      </Data>
    </list>
  </User>
  <User>
    <Name>User2</Name>
    <list xid="data.set">
      <Data>
        <Type>Vegetables</Type>
        <Column>8</Column>
        <RowValue>Squash</RowValue>
      </Data>
      <Data>
        <Column>3</Column>
        <Type>Sweets</Type>
        <RowValue>cake</RowValue>
        <RowValue>cookies</RowValue>
      </Data>
      <Data>
        <Column>5</Column>
        <Type>Other</Type>
      </Data>
      <Data>
        <Column>6</Column>
        <Type>Beverage</Type>
        <RowValue>grape juice</RowValue>
      </Data>
    </list>
    </User>
  <User>
    <Name>User4</Name>
    <list xid="data.set">
        <Data>
          <Column>7</Column>
          <Type>Fats</Type>
          <RowValue>cashews</RowValue>
        </Data>
        <Data>
          <Column>8</Column>
          <Type>Vegetables</Type>
          <RowValue>Green Beans</RowValue>
        </Data>
        <Data>
          <Column>2</Column>
          <Type>Carbs</Type>
          <RowValue>Brown Rice</RowValue>
        </Data>
      </list>
    </User>
    <User>
      <Name>User5</Name>
      <list xid="data.set">
        <Data>
          <Column>3</Column>
          <Type>Sweets</Type>
          <RowValue>gummy worms</RowValue>
        </Data>
        <Data>
          <Column>4</Column>
          <Type>Fruit</Type>
          <RowValue>apples</RowValue>
        </Data>
      </list>
    </User>
    <User>
      <Name>User5</Name>
      <list xid="data.set">
        <Data>
          <Column>3</Column>
          <Type>Sweets</Type>
          <RowValue>gummy worms</RowValue>
        </Data>
        <Data>
          <Column>4</Column>
          <Type>Fruit</Type>
          <RowValue>grapes</RowValue>
        </Data>
      </list>
    </User>
    <User>
      <Name>User5</Name>
      <list xid="data.set">
        <Data>
          <Column>3</Column>
          <Type>Sweets</Type>
          <RowValue>gummy worms</RowValue>
        </Data>
        <Data>
          <Column>4</Column>
          <Type>Fruit</Type>
          <RowValue>grapes</RowValue>
        </Data>
      </list>
    </User>
</Records>
</Document>

编辑:在HTML输出那里,当用户名存在不止一次在表格单元重复值(见下文)。 我想除去存在于每个小区中的重复的值,如“树胶状蠕虫,胶状蠕虫,胶状虫”。 例如,有三个“users5”上市。 我想保持包含每一行“USER5”,但在每个单元的那些行的删除重复值。

<table border="1">
<thead>
<tr>
<th>
</th>
<th>Protein</th>
<th>Carbs</th>
<th>Sweets</th>
<th>Fruit</th>
<th>Other</th>
<th>Beverage</th>
<th>Fats</th>
<th>Vegetables</th>
</tr>
<tr>
<th></th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
</tr></thead><tbody><tr><th>User1</th>
<td>sausage, eggs, turkey</td>
<td>Oatmeal</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr><th>User2</th>
<td></td>
<td></td>
<td>cake, cookies</td>
<td></td>
<td></td>
<td>grape juice</td>
<td></td>
<td>Squash</td>
</tr>
<tr><th>User4</th>
<td></td>
<td>Brown Rice</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>cashews</td>
<td>Green Beans</td>
</tr>
<tr><th>User5</th>
<td></td>
<td></td>
<td>gummy worms, gummy worms, gummy worms</td>
<td>apples, grapes, grapes</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr><th>User5</th>
<td></td>
<td></td>
<td>gummy worms, gummy worms, gummy worms</td>
<td>apples, grapes, grapes</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr><th>User5</th>
<td></td>
<td></td>
<td>gummy worms, gummy worms, gummy worms</td>
<td>apples, grapes, grapes</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

这是我在努力使这项工作非常愚蠢的尝试。 我是个新手,温柔的请...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">


  <xsl:key name="food-by-Category" match="Data" use="Column" />
 <xsl:key name="food-by-Value" match="Columns" use="RowValue" />

  <xsl:template match="/Document/Records/User/list[@xid = 'data.set']">

 <table><tr>
    <xsl:for-each select="Data[count(. | key('food-by-Category', Column)[1]) = 1]">
      <!-- Sort by the Category -->
      <xsl:sort select="Column" />
 <td>
      <xsl:value-of select="Type" />
</td>
</xsl:for-each>
</tr>

  <xsl:for-each select="Data[count(. | key('food-by-Category', Column)[1]) = 1]">
 <tr>
      <xsl:for-each select="key('food-by-Category', Column)">
         <!-- Sort by the item Value -->
        <xsl:sort select="RowValue" />
<td>
        <xsl:value-of select="RowValue" />
</td>      
    </xsl:for-each>
 </tr>
</xsl:for-each>
</table>
  </xsl:template>
</xsl:stylesheet>

正如你可以看到它不是分组表头/细胞一起或串联的值,当有多个<RowValue>。

Answer 1:

哇。 我想你在那里至少有三个不同的问题的价值:

  1. 如何制造出独特的列标题;
  2. 如何从一个稀疏数组到一个表中的数据;
  3. 如何将多个匹配数据项连接成一个单元。

如果这还不够复杂,你确信这将是重整的最后一个用户的数据(使<Name>的子<list> ,而不是一个兄弟姐妹)。

总之,看看下面的样式表:

<?xml version="1.0" encoding="utf-8"?>
<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:key name="data_by_column" match="Data" use="Column" />
<xsl:key name="value_by_cell" match="RowValue" use="concat(ancestor::User/Name, '|', preceding-sibling::Column)" />

<xsl:template match="/">
<table border="1">
<thead>
    <tr>
        <th/>
        <!--unique column headers -->
        <xsl:for-each select="Document/Records/User/list/Data[count(. | key('data_by_column', Column)[1]) = 1]">
        <xsl:sort select="Column" data-type="number" order="ascending"/>
        <th><xsl:value-of select="Type"/></th>
        </xsl:for-each>
    </tr>
    <tr>
        <th/>
        <!--unique column headers -->
        <xsl:for-each select="Document/Records/User/list/Data[count(. | key('data_by_column', Column)[1]) = 1]">
        <xsl:sort select="Column" data-type="number" order="ascending"/>
        <th><xsl:value-of select="Column"/></th>
        </xsl:for-each>
    </tr>
</thead>
<tbody>
    <xsl:for-each select="Document/Records/User">
    <xsl:variable name="row" select="Name" />
    <tr>
        <th><xsl:value-of select="$row"/></th>
        <!-- for each unique column header -->
        <xsl:for-each select="/Document/Records/User/list/Data[count(. | key('data_by_column', Column)[1]) = 1]">
        <xsl:sort select="Column" data-type="number" order="ascending"/>
        <xsl:variable name="col" select="Column" />
        <!-- new cell -->
        <td>
            <!-- get matching data -->
            <xsl:for-each select="key('value_by_cell', concat($row, '|', $col))">
                <xsl:value-of select="."/>
                <xsl:if test="position()!=last()">
                    <xsl:text>, </xsl:text>
                </xsl:if>
            </xsl:for-each>     
        </td>
        </xsl:for-each>
    </tr>
    </xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>

注:我可以消除可能通过先卸到一个变量重复相同的代码,唯一的列标题三次,但我跑出去的时间。



Answer 2:

我这样做是使用递归模板。 我只是没有对数据进行排序,并且列的数量是硬连线的。 你可以提高它添加一个关键与所有列和选择人数最多,或通过一个变量或参数设置它。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

    <xsl:output method="html" indent="yes"/>

    <xsl:key name="food-by-Category" match="Data" use="Type" />

    <!-- Match the Records tree, set the table elements and first row -->
    <xsl:template match="Records">
        <table width="800" border="1">
            <tbody>
                <tr>
                    <td>Name</td>
                    <xsl:for-each select="User/list/Data[count(. | key('food-by-Category', Type)[1]) = 1]">
                        <td><xsl:value-of select="Type"/></td>
                    </xsl:for-each>
                </tr>
                <!-- Apply the templates for each User subtree -->
                <xsl:apply-templates select="User" />
            </tbody>
        </table>
    </xsl:template>

    <!-- Set up one row for each User, get User name -->
    <xsl:template match="User">
        <tr>
            <td><xsl:value-of select="Name"/></td>
            <!-- Apply the templates for the list subtree -->
            <xsl:apply-templates select="list" />
        </tr>
    </xsl:template>

    <!-- This is a recursive template used to generate the columns 
         It's hardwired to generate 8 columns -->
    <xsl:template name="empty-tds">
        <xsl:param name="columns" />
        <xsl:param name="i" />
        <xsl:if test="$i &lt;= 8">
            <!-- Fills in each column with RowValues -->
            <td><xsl:apply-templates select="Data[Column = $i]/RowValue" /></td>
            <xsl:call-template name="empty-tds">
                <xsl:with-param name="i" select="$i + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- This calls the template above and generates columns -->
    <xsl:template match="list">
        <xsl:call-template name="empty-tds">
            <xsl:with-param name="i" select="1" />
        </xsl:call-template>
    </xsl:template>

    <!-- This one concatenates multiple RowValues within Data -->
    <xsl:template match="RowValue">
        <xsl:value-of select="."/>
        <xsl:if test="position() != last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

最后一个用户(#6)不会因为在它被放置在内部的源极印刷list



文章来源: Create A Table w/ XSLT 1.0 & Concatenate Multiple Values
标签: xml xslt