我如何获取此 xml 并为每个“部分”元素创建一个包含一列的表,然后使用 xslt 显示该列中的所有“文档”元素?
<Documents>
<Section>
<SectionName>Green</SectionName>
<Document>
<FileName>Tier 1 Schedules</FileName>
</Document>
<Document>
<FileName>Tier 3 Schedules</FileName>
</Document>
<Document>
<FileName>Setback Schedule</FileName>
</Document>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
<Section>
<SectionName>MRO/Refurb</SectionName>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
谢谢, 艾尔
最佳答案
此解决方案不使用递归,并重点介绍了一些有用的 XSLT 技术,例如 Muenchian 分组、键、查找最大值和不使用递归进行迭代。
这个转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kSectsByValue" match="SectionName"
use="."/>
<xsl:key name="kDocBySect" match="Document"
use="../SectionName"/>
<xsl:variable name="vCols" select=
"/*/*/SectionName
[generate-id()
=
generate-id(key('kSectsByValue',.)[1])
]"/>
<xsl:variable name="vMaxRows">
<xsl:for-each select="$vCols">
<xsl:sort data-type="number" order="descending"
select="count(key('kDocBySect', .))" />
<xsl:if test="position() = 1">
<xsl:value-of select="count(key('kDocBySect', .))"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<table>
<tr>
<xsl:apply-templates select="$vCols"/>
</tr>
<xsl:for-each select=
"(/*/*/Document)[not(position() > $vMaxRows)]">
<tr>
<xsl:variable name="vPos" select="position()"/>
<xsl:for-each select="$vCols">
<td>
<xsl:value-of select=
"../Document[$vPos]/FileName"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template match="SectionName">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
应用于原始 XML 文档时(已更正为格式正确):
<Documents>
<Section>
<SectionName>Green</SectionName>
<Document>
<FileName>Tier 1 Schedules</FileName>
</Document>
<Document>
<FileName>Tier 3 Schedules</FileName>
</Document>
<Document>
<FileName>Setback Schedule</FileName>
</Document>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
<Section>
<SectionName>MRO/Refurb</SectionName>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
</Documents>
产生期望的结果:
<table>
<tr>
<td>Green</td>
<td>MRO/Refurb</td>
</tr>
<tr>
<td>Tier 1 Schedules</td>
<td>Tier 2 Governance</td>
</tr>
<tr>
<td>Tier 3 Schedules</td>
<td/>
</tr>
<tr>
<td>Setback Schedule</td>
<td/>
</tr>
<tr>
<td>Tier 2 Governance</td>
<td/>
</tr>
</table>
请注意:
我们使用 Muenchian method for grouping 为了找到所有不同的列名,而不是依赖于它们在 XML 文档中的唯一性。
Keys用于 Muenchian 分组和查找属于一列的所有项目。
找到最大行数并保存在变量
$vMaxRows
我们迭代 N 次以生成表格的 N 行 -- 不使用递归!
第
N
行是通过将模板应用于在其列中位置为N
的所有列项而输出的。
关于xml - xslt:如何使用 xslt 创建具有多列和多行的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/768665/