2010-06-11 53 views
1

如何让代码更美观(紧凑)?如何简化使用许多“if”测试的XSLT?

<xsl:template match="part"> 
    <table class="part"> 
     <xsl:if test="name != ''"> 
      <tr> 
       <td>Название</td><td><xsl:value-of select="name"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="model != ''"> 
      <tr> 
       <td>Модель</td><td><xsl:value-of select="model"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="year != ''"> 
      <tr> 
       <td>Год</td><td><xsl:value-of select="year"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="glass_type != ''"> 
      <tr> 
       <td>Тип</td><td><xsl:value-of select="glass_type"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="scancode != ''"> 
      <tr> 
       <td>Сканкод</td><td><xsl:value-of select="scancode"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="eurocode != ''"> 
      <tr> 
       <td>Еврокод</td><td><xsl:value-of select="eurocode"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="coment != ''"> 
      <tr> 
       <td>Комментарий</td><td><xsl:value-of select="coment"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="glass_size != ''"> 
      <tr> 
       <td>Размер</td><td><xsl:value-of select="glass_size"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="vendor != ''"> 
      <tr> 
       <td>Производитель</td><td><xsl:value-of select="vendor"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="trademark != ''"> 
      <tr> 
       <td>Торговая марка</td><td><xsl:value-of select="trademark"/></td> 
      </tr> 
     </xsl:if> 
     <xsl:if test="fprice != ''"> 
      <tr> 
       <td>Цена</td><td><xsl:value-of select="fprice"/></td> 
      </tr> 
     </xsl:if> 
    </table> 
</xsl:template> 

更新:

我写道:

<my:translations xmlns:my="my:my"> 
    <w e="name" r="Название"/> 
    <w e="model" r="Модель"/> 
    <w e="year" r="Год"/> 
    <w e="glass_type" r="Тип"/> 
    <w e="scancode" r="Сканкод"/> 
    <w e="eurocode" r="Еврокод"/> 
    <w e="comment" r="Комментарий"/> 
    <w e="glass_size" r="Размер"/> 
    <w e="vendor" r="Производитель"/> 
    <w e="trademark" r="Торговая марка"/> 
    <w e="fprice" r="Цена"/> 
</my:translations> 

<xsl:value-of select="count(document('')//w)"/> 

给出0

+0

好问题(+1)。查看我的答案获得完整的解决方案。 :) – 2010-06-11 13:23:20

回答

2

该转化(44线,14是词典):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" exclude-result-prefixes="my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kTranslate" 
     match="w/@r" use="../@e"/> 

<my:translations> 
    <w e="name" r="Название"/> 
    <w e="model" r="Модель"/> 
    <w e="year" r="Год"/> 
    <w e="glass_type" r="Тип"/> 
    <w e="scancode" r="Сканкод"/> 
    <w e="eurocode" r="Еврокод"/> 
    <w e="comment" r="Комментарий"/> 
    <w e="glass_size" r="Размер"/> 
    <w e="vendor" r="Производитель"/> 
    <w e="trademark" r="Торговая марка"/> 
    <w e="fprice" r="Цена"/> 
</my:translations> 

<xsl:template match="part"> 
    <table class="part"> 
    <xsl:apply-templates/> 
    </table> 
</xsl:template> 

<xsl:template match="part/*"> 
    <xsl:variable name="vName" select="name()"/> 

    <xsl:variable name="vRName"> 
    <xsl:for-each select="document('')"> 
     <xsl:value-of select="key('kTranslate', $vName)"/> 
    </xsl:for-each> 
    </xsl:variable> 

    <tr> 
    <td><xsl:value-of select="$vRName"/></td> 
    <td><xsl:value-of select="."/></td> 
    </tr> 
</xsl:template> 
</xsl:stylesheet> 

当此XML文档上施加:

<object> 
    <part> 
    <name>FooName</name> 
    <model>FooName</model> 
    <year>FooName</year> 
    <glass_type>Fooglass_type</glass_type> 
    <scancode >Fooscancode</scancode> 
    <eurocode>Fooeurocode</eurocode> 
    <comment>Foocomment</comment> 
    <glass_size>Fooglass_size</glass_size> 
    <vendor>Foovendor</vendor> 
    <trademark>Footrademark</trademark> 
    <fprice>Foofprice</fprice> 
    </part> 
</object> 

产生想要的,正确的结果

<table class="part"> 
    <tr> 
     <td>Название</td> 
     <td>FooName</td> 
    </tr> 
    <tr> 
     <td>Модель</td> 
     <td>FooName</td> 
    </tr> 
    <tr> 
     <td>Год</td> 
     <td>FooName</td> 
    </tr> 
    <tr> 
     <td>Тип</td> 
     <td>Fooglass_type</td> 
    </tr> 
    <tr> 
     <td>Сканкод</td> 
     <td>Fooscancode</td> 
    </tr> 
    <tr> 
     <td>Еврокод</td> 
     <td>Fooeurocode</td> 
    </tr> 
    <tr> 
     <td>Комментарий</td> 
     <td>Foocomment</td> 
    </tr> 
    <tr> 
     <td>Размер</td> 
     <td>Fooglass_size</td> 
    </tr> 
    <tr> 
     <td>Производитель</td> 
     <td>Foovendor</td> 
    </tr> 
    <tr> 
     <td>Торговая марка</td> 
     <td>Footrademark</td> 
    </tr> 
    <tr> 
     <td>Цена</td> 
     <td>Foofprice</td> 
    </tr> 
</table> 

请注意

字典被放置在一个全球命名空间中的元素 - 仅用于演示的目的,为了能够在一个单一的样式呈现的一切。

在实际情况下,字典将占用其自己的XML文件。然后它将被访问:

 <xsl:variable name="vRName"> 
     <xsl:for-each select="document('dictionaryFileName.xml')"> 
      <xsl:value-of select="key('kTranslate', $vName)"/> 
     </xsl:for-each> 
     </xsl:variable> 
+0

@Dimitre Novatchev,如何修改代码,考虑到我最好不要更改'xsl:stylesheet'这个事实 - 我不能把'xmlns:my =“my:my”这个属性立即出现在我们所有的网站上,但有超过400个。 – Kalinin 2010-06-11 13:40:05

+0

@Kalinin:你可以在“my:translations”元素中声明命名空间 – 2010-06-11 13:54:42

+1

@Kalinin:查找表通常放在一个单独的XML文档中,该文档使用' document()函数。为了方便,我将查找元素作为样式表中的全局元素。至于'my:'命名空间的传播,我完全不明白这一点。 'exclude-result-prefixes =“my”'完全是为了防止这种情况 - 并且在我的转换结果中不会发生这种传播。 – 2010-06-11 14:20:12

0

如果源XML节点出现在相同的顺序为您设定的,如果测试或输出的顺序并不重要,那么你可以使用xsl:apply-templates select="*" mode="tr"/>并编写一个模板,如

<xsl:template match="*" mode="tr"> 
      <tr> 
       <td>...</td><td><xsl:value-of select="." /></td> 
      </tr> 
</xsl:template> 

在第一td(...),你既可以使用xsl:choose & xsl:when,键入上local-name(.)或另一个模板,以转化为西里尔。

如果输入xml的顺序不同,并且输出xml的顺序很重要,那么此解决方案将不起作用。