我有XML包含描述对象类型和名称的元素。对象按类型分为Animated = [Dog,Person]和Inanimate = [Plant,Automobile]类别。下面显示了一个示例XML和所需的HTML。
我还希望有一个全能的XSL模板,告诉我哪些类型,例如猫,无法映射到Animate / Inanimate组。
我正在使用Saxon 9.4。
XML:
<items>
<item>
<type>Dog</type>
<name>Fido</name>
</item>
<item>
<type>Person</type>
<name>Bob</name>
</item>
<item>
<type>Plant</type>
<name>Tomato</name>
</item>
<item>
<type>Automobile</type>
<name>Honda</name>
</item>
<item>
<type>Automobile</type>
<name>Ford</name>
</item>
HTML:
<table>
<th>There are 2 Animated objects</th>
<tr>
<td>Dog Fido</td>
<td>Person Bob</td>
</tr>
</table>
<table>
<th>There are 3 Inanimate objects</th>
<tr>
<td>Plant Tomato</td>
<td>Automobile Honda</td>
<td>Automobile Ford</td>
</tr>
</table>
*添加以下内容以回应评论*
某些对象类型与Animate / Inanimate组之间的映射是经验已知的,但映射不完整。因此,在这个表面的例子中,如果遇到Cat类型,则需要在catch-all模板中打印出来。
我遇到的最大问题是打印单个并打印多个<tr>
。我尝试在<th>
的模板中打印match="items[item/type='Dog'] | items[item/type='Person']"
,然后递归<xsl:apply-template select="items"/>
,但后来我不知道如何为我所做的类型的项目执行全部检查t占,例如Cat。
我还尝试使用match="item[type='Dog' or type='Person']"
制作模板,但为了打印<th>
,我必须<xsl:if test="position() = 1">
打印<table><th>..</th>
。但这不起作用,因为在我处理组中的最后一项之前,XSLT中没有关闭</table>
。
我希望这能澄清我的困境。
谢谢,
艾力
答案 0 :(得分:1)
假设您使用XSLT 2.0,您可以使用所需的映射定义参数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:param name="map">
<map>
<key name="Dog">Animated</key>
<key name="Person">Animated</key>
<key name="Plant">Inanimate</key>
<key name="Automobile">Inanimate</key>
</map>
</xsl:param>
<xsl:strip-space elements="*"/>
<xsl:output method="html" indent="yes" version="5.0"/>
<xsl:key name="k1" match="map/key" use="@name"/>
<xsl:template match="items">
<xsl:for-each-group select="item" group-by="(key('k1', type, $map), 'unmapped')[1]">
<table>
<thead>
<tr>
<th>There are <xsl:value-of select="count(current-group()),
current-grouping-key()"/>
objects.</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="current-group()"/>
</tbody>
</table>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="item">
<tr>
<xsl:value-of select="*"/>
</tr>
</xsl:template>
</xsl:stylesheet>
那样输入样本
<items>
<item>
<type>Dog</type>
<name>Fido</name>
</item>
<item>
<type>Person</type>
<name>Bob</name>
</item>
<item>
<type>Plant</type>
<name>Tomato</name>
</item>
<item>
<type>Automobile</type>
<name>Honda</name>
</item>
<item>
<type>Automobile</type>
<name>Ford</name>
</item>
<item>
<type>Cat</type>
<name>Garfield</name>
</item>
</items>
转换为
<table>
<thead>
<tr>
<th>There are 2 Animated
objects.
</th>
</tr>
</thead>
<tbody>
<tr>Dog Fido</tr>
<tr>Person Bob</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>There are 3 Inanimate
objects.
</th>
</tr>
</thead>
<tbody>
<tr>Plant Tomato</tr>
<tr>Automobile Honda</tr>
<tr>Automobile Ford</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>There are 1 unmapped
objects.
</th>
</tr>
</thead>
<tbody>
<tr>Cat Garfield</tr>
</tbody>
</table>