慕尼黑?XSLT 去规范化/旋转/展平 xml 文件? [英] Muenchian? XSLT to denormalize/pivot/flatten xml file?

查看:31
本文介绍了慕尼黑?XSLT 去规范化/旋转/展平 xml 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个具有以下结构的输入 xml 文件:

Given an input xml file with following structure:

<root>
  <record row="1" col="1" val="1" />
  <record row="1" col="2" val="2" />
  <record row="1" col="3" val="3" />
  <record row="1" col="n" val="4" />
  <record row="2" col="1" val="5" />
  <record row="2" col="3" val="6" />
  <record row="2" col="n" val="7" />
  <record row="n" col="2" val="8" />
  <record row="n" col="3" val="9" />
  <record row="n" col="n" val="10" />
</root>

如何使用 XSLT 输出以下结构?

How can I output the following structure using XSLT?

<root>
  <row id="1">
    <col id="1">1</col>
    <col id="2">2</col>
    <col id="3">3</col>
    <col id="n">4</col>
  </row>
  <row id="2">
    <col id="1">5</col>
    <col id="2"></col>
    <col id="3">6</col>
    <col id="n">7</col>
  </row>
  <row id="n">
    <col id="1"></col>
    <col id="2">8</col>
    <col id="3">9</col>
    <col id="n">10</col>
  </row>
</root>

[注意即使输入中没有相关元素,所有列是如何输出的]

[Note how all columns are output even if there is no related element in input]

在我的示例中使用数字和字母可能会引起混淆.我正在寻找的解决方案需要处理非数字的行和列属性.

I may have caused confusion through the use of numbers and letters in my example. The solution I am looking for needs to handle row and column attributes that are non-numeric.

推荐答案

这个问题的答案展示了解决问题的可能方法:

The answers to this question show possible ways to approach the problem:

xslt:如何使用 xslt 创建具有多列和多行的表?

结合了链接问题中所见技术的解决方案如下.

A solution that incorporates the techniques seen in the linked question follows.

我假设:

  • 您的@row@col 属性是递增的数字,用于定义表中记录的位置,它们不能真正包含字符串"n".因此,它们在整个文档中并不是唯一的,这使得它们不适合作为 HTML @id 属性.我在输出中用 @title 属性替换了它们.
  • 没有隐式空行(@row 连续性中的间隙不会产生空行),只有隐式空单元格.
  • 每个 @row@col 组合都是唯一的.
  • your @row and @col attributes are incrementing numbers that define the position of the record in the table, and they cannot really contain the string "n". As such they are not unique throughout the document, which makes them unsuitable as HTML @id attributes. I substituted them by @title attributes in my output.
  • there are no implicit empty rows (gaps in @row continuity will not produce empty rows), only implicit empty cells.
  • every @row and @col combination is unique.

这个 XSLT 1.0 转换:

This XSLT 1.0 transformation:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <!-- prepare some keys for later use -->
  <xsl:key name="kRecordsByRow" match="record" use="@row" />
  <xsl:key name="kRecordsByPos" match="record" use="concat(@row, ',', @col)" />

  <!-- find out the highest @col number -->
  <xsl:variable name="vMaxCol">
    <xsl:for-each select="/root/record">
      <xsl:sort select="@col" data-type="number" order="descending" />
      <xsl:if test="position() = 1">
        <xsl:value-of select="@col" />
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <!-- select the <record>s that are the first in their rows -->
  <xsl:variable name="vRows" select="
    /root/record[
      generate-id()
      =
      generate-id(key('kRecordsByRow', @row)[1])
    ]
  " />  

  <!-- output basic table structure -->
  <xsl:template match="/root">
    <table>
      <xsl:for-each select="$vRows">
        <xsl:sort select="@row" data-type="number" />
        <tr title="{@row}">
          <xsl:call-template name="td" />
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>

  <!-- output the right number of <td>s in each row, empty or not -->
  <xsl:template name="td">
    <xsl:param name="col" select="1" />

    <td title="{$col}">
      <xsl:value-of select="key('kRecordsByPos', concat(@row, ',', $col))/@val" />
    </td>

    <xsl:if test="$col &lt; $vMaxCol">
      <xsl:call-template name="td">
        <xsl:with-param name="col" select="$col + 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

...当应用于这个(稍微修改)输入时:

…when applied to this (slightly modified) input:

<root>
  <record row="1" col="1" val="1" />
  <record row="1" col="2" val="2" />
  <record row="1" col="3" val="3" />
  <record row="1" col="4" val="4" />
  <record row="2" col="1" val="5" />
  <record row="2" col="3" val="6" />
  <record row="2" col="4" val="7" />
  <record row="3" col="2" val="8" />
  <record row="3" col="3" val="9" />
  <record row="3" col="4" val="10" />
</root>

…产生:

<table>
  <tr title="1">
    <td title="1">1</td>
    <td title="2">2</td>
    <td title="3">3</td>
    <td title="4">4</td>
  </tr>
  <tr title="2">
    <td title="1">5</td>
    <td title="2"></td>
    <td title="3">6</td>
    <td title="4">7</td>
  </tr>
  <tr title="3">
    <td title="1"></td>
    <td title="2">8</td>
    <td title="3">9</td>
    <td title="4">10</td>
  </tr>
</table>

  • Muenchian分组用于选择每个@row组的前s
  • an 用于通过记录的位置查明记录
  • 递归用于产生一组一致的,独立于指定位置的的实际存在
    • Muenchian grouping is used to select the first <record>s of each @row group
    • an <xsl:key> is used to pinpoint a record by it's position
    • recursion is used to produce a consistent set of <td>s, independent of the actual existence of a <record> at the named position
    • 这篇关于慕尼黑?XSLT 去规范化/旋转/展平 xml 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆