我有一个包含很多未知数的非常大的XML文件的摘录。这个XML文件包含许多conceptGrps,每个都可以包含不同数量的languageGrps / languages,而这些语言可以包含不同数量的术语。
<mtf>
<conceptGrp>
<concept>1</concept>
<languageGrp>
<language lang="DE" type="Deutsch"/>
<termGrp>
<term>Abbildung</term>
</termGrp>
</languageGrp>
<languageGrp>
<language lang="PL" type="Polnisch"/>
<termGrp>
<term>ilustracja</term>
</termGrp>
</languageGrp>
<languageGrp>
<language lang="RU" type="Russisch"/>
<termGrp>
<term>иллюстрация</term>
</termGrp>
<termGrp>
<term>рисунок</term>
</termGrp>
</languageGrp>
<languageGrp>
<language lang="CS" type="Tschechisch"/>
<termGrp>
<term>vyobrazení</term>
<descripGrp>
<descrip type="Autor">MK</descrip>
</descripGrp>
</termGrp>
</languageGrp>
</conceptGrp>
</mtf>
我需要一个能满足各种可能性的html表。表格的形式应为:
对于每种语言(无论多少),单独的行和每个术语都有一个单独的行 - 如下所示:如果有超过1个术语将它们视为同义词并显示在同一行中,这一点非常重要如下例所示。
Concept Deutsch Polnisch Russisch Tschechisch
1 Abbildung ilustracja иллюстрация vyobrazení
1 рисунок
我的问题:有时第一语言Grp有超过1个术语,有时是第三个,...我试图将conceptGrps组合在一起并且没有问题以复杂的方式 - )这是我的版本,但我必须因为我永远不知道有多少种语言,术语......可能会对每个新文件进行调整。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:template match="mtf">
<html>
<body>
<h2>Terminologie</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="conceptGrp">
<xsl:for-each select=".">
<table>
<tr> <!--Zeile 1-->
<td>Konzept-ID</td>
<xsl:for-each select="languageGrp">
<td><xsl:value-of select="language/@type"/></td> <!--Spalte2-->
</xsl:for-each>
</tr>
<tr> <!--Zeile 2-->
<td><xsl:value-of select="concept"/></td> <!--Spalte1-->
<xsl:for-each select="languageGrp//termGrp[1]">
<td><xsl:value-of select="term"/></td> <!--Spalte2-->
</xsl:for-each>
</tr>
<xsl:if test="languageGrp//termGrp[2]">
<tr>
<td><xsl:value-of select="concept"/></td>
<td><xsl:value-of select="languageGrp[1]//termGrp[2]/term"/></td>
<td><xsl:value-of select="languageGrp[2]//termGrp[2]/term"/></td>
<td><xsl:value-of select="languageGrp[3]//termGrp[2]/term"/></td>
<td><xsl:value-of select="languageGrp[4]//termGrp[2]/term"/></td>
</tr>
</xsl:if>
</table>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
有人能以更优雅,更全面的方式推动我吗?非常感谢。
答案 0 :(得分:1)
这是我能想到的最好的设计,但我认为它可以满足您的一切需求:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:key name="kLang" match="languageGrp" use="language/@lang" />
<xsl:variable name="uniqueLangs"
select="/mtf/conceptGrp/languageGrp
[generate-id() = generate-id(key('kLang', language/@lang)[1])]" />
<xsl:template match="mtf">
<html>
<body>
<h2>Terminologie</h2>
<table>
<tr>
<!--Zeile 1-->
<td>Konzept-ID</td>
<xsl:apply-templates select="$uniqueLangs" mode="header"/>
</tr>
<xsl:apply-templates select="conceptGrp" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="languageGrp" mode="header">
<td>
<xsl:value-of select="language/@type"/>
</td>
</xsl:template>
<xsl:template match="conceptGrp">
<xsl:apply-templates select="languageGrp" mode="maxGroup">
<xsl:sort select="count(termGrp)" order="descending" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="languageGrp" mode="maxGroup">
<!-- Only use the first group out of the sorting (most termGrps) -->
<xsl:if test="position() = 1">
<xsl:apply-templates select="termGrp" />
</xsl:if>
</xsl:template>
<xsl:template match="termGrp">
<xsl:variable name="pos" select="position()" />
<xsl:variable name="currConcept" select="../.." />
<tr>
<td>
<xsl:value-of select="$currConcept/concept"/>
</td>
<!-- Iterate through all of the distinct languages -->
<xsl:for-each select="$uniqueLangs">
<td>
<!-- Get the term for the current language and position,
within the current concept -->
<xsl:value-of
select="$currConcept/languageGrp
[language/@lang = current()/language/@lang]
/termGrp[$pos]/term"/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时,会产生:
<html>
<body>
<h2>Terminologie</h2>
<table>
<tr>
<td>Konzept-ID</td>
<td>Deutsch</td>
<td>Polnisch</td>
<td>Russisch</td>
<td>Tschechisch</td>
</tr>
<tr>
<td>1</td>
<td>Abbildung</td>
<td>ilustracja</td>
<td>иллюстрация</td>
<td>vyobrazení</td>
</tr>
<tr>
<td>1</td>
<td></td>
<td></td>
<td>рисунок</td>
<td></td>
</tr>
</table>
</body>
</html>
您的原始尝试看起来像是将每个概念放入一个单独的表中,但这是故意的吗?您是否希望每个概念在一个不同的表中只包含该概念的语言,或者所有可用语言的单个表中的所有概念?