XSL 转换 - XML 数据到不同的 HTML 表
XSL transformation - XML data to different HTML tables
你好,这个 XML 代码的 XSL 样式表看起来如何?我根据这个问题(如下)尝试了一些方法,但我的输出看起来不像下面我想要的那样。
XML代码
<?xml version="1.0" encoding="utf-8" ?>
<root>
<sample time="14" label="Test1:cpu_2:usage_high">
<value>96</value>
</sample>
<sample time="14" label="Test1:cpu_2:usage_low">
<value>1</value>
</sample>
<sample time="1" label="Test1:cpu_1:usage_high">
<value>97</value>
</sample>
<sample time="1" label="Test1:cpu_2:usage_low">
<value>7</value>
</sample>
<sample time="1" label="Test1:cpu_1:usage_low">
<value>6</value>
</sample>
<sample time="14" label="Test1:cpu_1:usage_low">
<value>11</value>
</sample>
<sample time="1" label="Test1:cpu_2:usage_high">
<value>91</value>
</sample>
<sample time="14" label="Test1:cpu_1:usage_high">
<value>89</value>
</sample>
</root>
HTML代码
<html>
<body>
<h2>CPU1</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>97</td>
<td>6</td>
</tr>
<tr>
<td>14</td>
<td>89</td>
<td>11</td>
</tr>
</tbody>
</table>
<h2>CPU2</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>91</td>
<td>7</td>
</tr>
<tr>
<td>14</td>
<td>96</td>
<td>1</td>
</tr>
</tbody>
</table>
</body>
</html>
您应该首先按 cpu 数字对 sample
元素进行分组(当被 :
标记时 @label
中的第二个标记)。
然后按 @time
分组以获得每一行。
示例...
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<html>
<body>
<xsl:for-each-group select="sample" group-by="tokenize(@label, ':')[2]">
<xsl:sort select="current-grouping-key()"/>
<h2>
<xsl:value-of select="upper-case(replace(current-grouping-key(), '_', ''))"/>
</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="current-group()" group-by="@time">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<td>
<xsl:value-of select="current-group()[ends-with(@label, 'high')]/value"/>
</td>
<td>
<xsl:value-of select="current-group()[ends-with(@label, 'low')]/value"/>
</td>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
输出
<html>
<body>
<h2>CPU1</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>97</td>
<td>6</td>
</tr>
<tr>
<td>14</td>
<td>89</td>
<td>11</td>
</tr>
</tbody>
</table>
<h2>CPU2</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>91</td>
<td>7</td>
</tr>
<tr>
<td>14</td>
<td>96</td>
<td>1</td>
</tr>
</tbody>
</table>
</body>
</html>
可以在这里看到一个工作示例:http://xsltfiddle.liberty-development.net/eiQZDbq
这是另一个更通用的选项。它只处理带有第三个标记的标签属性的样本...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:local="local">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="local:format">
<xsl:param name="str"/>
<xsl:param name="delim"/>
<xsl:variable name="tokens" as="item()*">
<xsl:for-each select="tokenize($str,$delim)">
<xsl:sequence select="concat(upper-case(substring(.,1,1)),substring(.,2))"/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($tokens, ' ')"/>
</xsl:function>
<xsl:template match="/*">
<html>
<body>
<xsl:for-each-group select="sample[tokenize(@label,':')[3]]" group-by="tokenize(@label, ':')[2]">
<xsl:sort select="current-grouping-key()"/>
<xsl:variable name="cols" select="distinct-values(current-group()/@label/tokenize(.,':')[3])" as="item()*"/>
<h2>
<xsl:value-of select="upper-case(replace(current-grouping-key(), '_', ''))"/>
</h2>
<table>
<thead>
<tr>
<th>Time</th>
<xsl:for-each select="$cols">
<th>
<xsl:value-of select="local:format(.,'_')"/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="current-group()" group-by="@time">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<xsl:for-each select="$cols">
<td>
<xsl:value-of select="current-group()[ends-with(@label, current())]/value"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
你好,这个 XML 代码的 XSL 样式表看起来如何?我根据这个问题(如下)尝试了一些方法,但我的输出看起来不像下面我想要的那样。
XML代码
<?xml version="1.0" encoding="utf-8" ?>
<root>
<sample time="14" label="Test1:cpu_2:usage_high">
<value>96</value>
</sample>
<sample time="14" label="Test1:cpu_2:usage_low">
<value>1</value>
</sample>
<sample time="1" label="Test1:cpu_1:usage_high">
<value>97</value>
</sample>
<sample time="1" label="Test1:cpu_2:usage_low">
<value>7</value>
</sample>
<sample time="1" label="Test1:cpu_1:usage_low">
<value>6</value>
</sample>
<sample time="14" label="Test1:cpu_1:usage_low">
<value>11</value>
</sample>
<sample time="1" label="Test1:cpu_2:usage_high">
<value>91</value>
</sample>
<sample time="14" label="Test1:cpu_1:usage_high">
<value>89</value>
</sample>
</root>
HTML代码
<html>
<body>
<h2>CPU1</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>97</td>
<td>6</td>
</tr>
<tr>
<td>14</td>
<td>89</td>
<td>11</td>
</tr>
</tbody>
</table>
<h2>CPU2</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>91</td>
<td>7</td>
</tr>
<tr>
<td>14</td>
<td>96</td>
<td>1</td>
</tr>
</tbody>
</table>
</body>
</html>
您应该首先按 cpu 数字对 sample
元素进行分组(当被 :
标记时 @label
中的第二个标记)。
然后按 @time
分组以获得每一行。
示例...
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<html>
<body>
<xsl:for-each-group select="sample" group-by="tokenize(@label, ':')[2]">
<xsl:sort select="current-grouping-key()"/>
<h2>
<xsl:value-of select="upper-case(replace(current-grouping-key(), '_', ''))"/>
</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="current-group()" group-by="@time">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<td>
<xsl:value-of select="current-group()[ends-with(@label, 'high')]/value"/>
</td>
<td>
<xsl:value-of select="current-group()[ends-with(@label, 'low')]/value"/>
</td>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
输出
<html>
<body>
<h2>CPU1</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>97</td>
<td>6</td>
</tr>
<tr>
<td>14</td>
<td>89</td>
<td>11</td>
</tr>
</tbody>
</table>
<h2>CPU2</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>High</th>
<th>Low</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>91</td>
<td>7</td>
</tr>
<tr>
<td>14</td>
<td>96</td>
<td>1</td>
</tr>
</tbody>
</table>
</body>
</html>
可以在这里看到一个工作示例:http://xsltfiddle.liberty-development.net/eiQZDbq
这是另一个更通用的选项。它只处理带有第三个标记的标签属性的样本...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:local="local">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="local:format">
<xsl:param name="str"/>
<xsl:param name="delim"/>
<xsl:variable name="tokens" as="item()*">
<xsl:for-each select="tokenize($str,$delim)">
<xsl:sequence select="concat(upper-case(substring(.,1,1)),substring(.,2))"/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($tokens, ' ')"/>
</xsl:function>
<xsl:template match="/*">
<html>
<body>
<xsl:for-each-group select="sample[tokenize(@label,':')[3]]" group-by="tokenize(@label, ':')[2]">
<xsl:sort select="current-grouping-key()"/>
<xsl:variable name="cols" select="distinct-values(current-group()/@label/tokenize(.,':')[3])" as="item()*"/>
<h2>
<xsl:value-of select="upper-case(replace(current-grouping-key(), '_', ''))"/>
</h2>
<table>
<thead>
<tr>
<th>Time</th>
<xsl:for-each select="$cols">
<th>
<xsl:value-of select="local:format(.,'_')"/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="current-group()" group-by="@time">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<xsl:for-each select="$cols">
<td>
<xsl:value-of select="current-group()[ends-with(@label, current())]/value"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</xsl:for-each-group>
</body>
</html>
</xsl:template>
</xsl:stylesheet>