2013-10-10 49 views
-3

我有XML,其中包含描述對象類型和名稱的元素。對象按類型分組爲Animated = [Dog,Person]和Inanimate = [Plant,Automobile]類別。示例XML和所需的HTML如下所示。XSLT:按類型輸出XML元素並將其輸出爲HTML表格

我也想有一個全面的XSL模板,告訴我哪些類型,例如Cat,無法映射到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類型,則需要將其打印在全部模板中。

我遇到的最大問題是打印出單張,並打印出多個<tr>。我嘗試在match="items[item/type='Dog'] | items[item/type='Person']"然後遞歸地<xsl:apply-template select="items"/>的模板中打印一個<th>,但後來我不知道如何處理類型爲I的項目(如Cat)。

我也試過有一個模板,match="item[type='Dog' or type='Person']",但爲了打印出<th>我不得不做<xsl:if test="position() = 1">打印出來<table><th>..</th>。但是這不起作用,因爲在處理組中最後一個項目之前,XSLT中沒有關閉</table>

我希望這可以澄清我的困境。

謝謝,

艾力

+0

具體來說,你有什麼嘗試過,它是如何失敗? – kjhughes

+0

好點,你的表現力不足。更不用說,你什麼也沒有展示出來,所有這些都是假設解釋動畫的無生命的......或者你是否期望將它嵌入到XSLT引擎中呢?彷彿它可以解釋這一點。 –

+0

Animate vs. Inanimate。這是個問題。你打算提供一個將「狗」映射到「動畫」和「汽車」到「無生命」的xml映射,或者你是否打算正確選擇一些冗長的IF/THEN CHOOSE/OTHERWISE功能邏輯?到目前爲止你做了什麼?這是直接從一本教科書嗎? – kstubs

回答

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> 
+0

簡直太棒了。馬丁,我希望我可以直接與你聯繫,但你網站的聯繫方式與我不合作。 – alecswan