-3

我有包含描述对象类型和名称的元素的 XML。对象按类型分为 Animated=[Dog, Person] 和 Inanimate=[Plant, Automobile] 类别。示例 XML 和所需的 HTML 如下所示。

我还想要一个包罗万象的 XSL 模板,它可以告诉我哪些类型(例如 Cat)不能映射到 Animate/Inanimate 组。

我正在使用撒克逊 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 模板中打印出来。

我遇到的最大问题是打印出 single 并打印出 multiple <tr>. <th>我尝试在具有match="items[item/type='Dog'] | items[item/type='Person']"然后递归的模板中打印 a <xsl:apply-template select="items"/>,但是我不知道如何对具有我没有考虑的类型的项目(例如 Cat.

我也尝试了一个模板match="item[type='Dog' or type='Person']",但是为了打印出来<th>我不得不<xsl:if test="position() = 1">打印出来<table><th>..</th>。但这不起作用,因为</table>在我处理组中的最后一项之前,XSLT 中没有关闭。

我希望这能澄清我的困境。

谢谢,

亚历克

4

1 回答 1

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>
于 2013-10-10T10:04:16.233 回答