我想创建一个组合表,其中包含来自xml源中不同子节点的数据。
源(大致)如下:请注意,我已经简化了示例。 "模式"在更大的xml文档和" BLOCK"中,节点是几个级别。节点不仅包含" CODE"儿童。 从三个不同的节点Mode1,Mode2和Mode3收集数据。源文档中有更多的ModeX(X = 1..10)节点,但它们不会进入此特定表。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="sample.xsl" type="text/xsl"?>
<root>
<!-- there are "a lot" more levels between root and Modes -->
<Modes>
<Mode1>
<KOMMENTAR>Header 1</KOMMENTAR>
<TEST>
<NUMBER>5</NUMBER>
<FLAG>0</FLAG>
</TEST>
<TEST>
<NUMBER>6</NUMBER>
<FLAG>0</FLAG>
</TEST>
<TEST>
<NUMBER>7</NUMBER>
<FLAG>1</FLAG>
<BLOCK>
<CODE>1.7.1 - Message</CODE>
</BLOCK>
</TEST>
<TEST>
<NUMBER>8</NUMBER>
<FLAG>1</FLAG>
<BLOCK>
<CODE>1.8.1 - Message</CODE>
</BLOCK>
<BLOCK>
<CODE>1.8.2 - Message</CODE>
</BLOCK>
</TEST>
<TEST>
<NUMBER>9</NUMBER>
<FLAG>0</FLAG>
<BLOCK>
<CODE>1.9.1 - Message</CODE>
</BLOCK>
</TEST>
</Mode1>
<Mode2>
<KOMMENTAR>Header 2</KOMMENTAR>
<TEST>
<NUMBER>5</NUMBER>
</TEST>
<TEST>
<NUMBER>6</NUMBER>
<BLOCK>
<CODE>2.6.1 - Message</CODE>
</BLOCK>
<BLOCK>
<CODE>2.6.2 - Message</CODE>
</BLOCK>
<BLOCK>
<CODE>2.6.2 - Message</CODE>
</BLOCK>
</TEST>
<TEST>
<NUMBER>7</NUMBER>
<BLOCK>
<CODE>2.7.1 - Message</CODE>
</BLOCK>
</TEST>
<TEST>
<NUMBER>8</NUMBER>
</TEST>
<TEST>
<NUMBER>9</NUMBER>
</TEST>
</Mode2>
<Mode3>
<KOMMENTAR>Header 3</KOMMENTAR>
<TEST>
<NUMBER>5</NUMBER>
</TEST>
<TEST>
<NUMBER>6</NUMBER>
</TEST>
<TEST>
<NUMBER>7</NUMBER>
<BLOCK>
<CODE>3.7.1 - Message</CODE>
</BLOCK>
<BLOCK>
<CODE>3.7.2 - Message that spans over several lines</CODE>
</BLOCK>
</TEST>
<TEST>
<NUMBER>8</NUMBER>
</TEST>
<TEST>
<NUMBER>9</NUMBER>
</TEST>
</Mode3>
<Mode9>
Contains some other data
</Mode9>
</Modes>
</root>
所需的输出是如下表格(以HTML格式显示):
| Header 1 | Header 2 | Header 3 | Test | Flag | Nr. | Message | Nr. | Message | Nr. | Message | 5 | 0 | | | | | | | 6 | 0 | | | 1 | 2.6.1 - Message | | | | | | | 2 | 2.6.2 - Message | | | | | | | 3 | 2.6.3 - Message | | | 7 | 1 | 1 | 1.7.1 - Message | 1 | 2.7.1 - Message | 1 | 3.7.1 - Message | | | | | | | 2 | 3.7.2 - Message | | | | | | | | that spans over | | | | | | | | several lines | 8 | 1 | 1 | 1.8.1 - Message | | | | | | | 2 | 1.8.2 - Message | | | | | 9 | 0 | | | | | | |
直到现在我能想出的最好的事情是为TEST下面的每个BLOCK创建一个子表。但这看起来很丑陋,因为当然是&#34; Nr。&#34;和&#34;消息&#34;标头不与子表的内容列对齐。
我已经阅读了一些关于Muenchian分组的文章(http://www.jenitennison.com/xslt/grouping/muenchian.html以及有关stackoverflow的其他问题)并尝试了这些示例,但我无法获得适合我数据的密钥。
如果有人可以帮助我使用键和外部for-each循环,我想我可以处理其余部分。
提前致谢。
答案 0 :(得分:0)
恕我直言,外环很容易,真正的问题出现了。以下是外循环的方法:如果有人可以帮助我使用键和外部for-each循环,我 我想我可以处理剩下的事了。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" encoding="UTF-8" version="1.0"/>
<xsl:key name="test" match="TEST" use="NUMBER" />
<xsl:template match="/">
<table border="1">
<thead>
<tr>
<th colspan="2"/>
<th colspan="2">Header 1</th>
<th colspan="2">Header 2</th>
<th colspan="2">Header 3</th>
</tr>
<tr>
<th>Test</th>
<th>Flag</th>
<th>Nr.</th>
<th>Message</th>
<th>Nr.</th>
<th>Message</th>
<th>Nr.</th>
<th>Message</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="(root/Modes/Mode1/TEST | root/Modes/Mode2/TEST | root/Modes/Mode3/TEST)[count(. | key('test', NUMBER)[1]) = 1]">
<tr>
<td><xsl:value-of select="NUMBER"/></td>
<td><xsl:value-of select="FLAG"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
此时您将拥有:
现在出现了一个真正的问题:如果您想要一个为每条消息编号的列并使该号码与相邻消息对齐,则必须为每个消息创建一个单独的行,而不是列中的第一个消息。您需要计算每列中的消息数,并使用这三个中的最大值作为前两个单元格的rowspan值。
或者,您可以采取简单的方法,并执行以下操作:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" encoding="UTF-8" version="1.0"/>
<xsl:key name="test" match="TEST" use="NUMBER" />
<xsl:template match="/">
<table border="1">
<thead>
<tr>
<th width="5%">Test</th>
<th width="5%">Flag</th>
<th width="30%">Header 1<br/>Message</th>
<th width="30%">Header 2<br/>Message</th>
<th width="30%">Header 3<br/>Message</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="(root/Modes/Mode1/TEST | root/Modes/Mode2/TEST | root/Modes/Mode3/TEST)[count(. | key('test', NUMBER)[1]) = 1]">
<tr>
<td><xsl:value-of select="NUMBER"/></td>
<td><xsl:value-of select="FLAG"/></td>
<td>
<ol>
<xsl:for-each select="key('test', NUMBER)[parent::Mode1]/BLOCK">
<li>
<xsl:value-of select="CODE"/>
</li>
</xsl:for-each>
</ol>
</td>
<td>
<ol>
<xsl:for-each select="key('test', NUMBER)[parent::Mode2]/BLOCK">
<li>
<xsl:value-of select="CODE"/>
</li>
</xsl:for-each>
</ol>
</td>
<td>
<ol>
<xsl:for-each select="key('test', NUMBER)[parent::Mode3]/BLOCK">
<li>
<xsl:value-of select="CODE"/>
</li>
</xsl:for-each>
</ol>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
生产:
可以使用CSS进一步按摩成形。