2010-09-05 57 views
5

我正在使用XSLT1.0来转换我的XML。检查起始字符应该是'T',接下来的3个字符应该是xslt中的数字

我有以下Tabs.xml

<?xml version="1.0"?> 
<tcm:ListItems xmlns:tcm="http://www.tridion.com/ContentManager/5.0" ID="tcm:481-87289-4" Managed="68"> 
    <tcm:Item ID="tcm:481-596728-64" Title="T000. Brisbane" pageURL="/australia/brisbane/index.aspx" componentTitle="Overview"/> 
    <tcm:Item ID="tcm:481-598671-64" Title="Tabs XML"/> 
    <tcm:Item ID="tcm:481-598672-64" Title="T030 Special Offers" pageURL="/australia/brisbane/specialoffers.aspx" componentTitle="Special Offers"/> 
    <tcm:Item ID="tcm:481-598673-64" Title="020 Flight Schedules" pageURL="/australia/brisbane/flightschedules.aspx" componentTitle="Flight Schedules"/> 
    <tcm:Item ID="tcm:481-598674-64" Title="T010 Guide" pageURL="/australia/brisbane/guide.aspx" componentTitle="Guide"/> 
</tcm:ListItems> 

,我使用下面的XSLT转换它!

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:em="http://www.emirates.com/tridion/schemas" xmlns:tcmse="http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant" exclude-result-prefixes="em xlink tcmse tcm"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-16" indent="yes"/> 
    <xsl:template match="tcm:ListItems"> 
    <list type="Tabs"> 
     <xsl:apply-templates select="tcm:Item"> 
     <xsl:sort select="@Title" order="ascending"/> 
     </xsl:apply-templates> 
    </list> 
    </xsl:template> 
    <!-- add field values for each item--> 
    <xsl:template match="tcm:Item"> 
    <xsl:if test="@componentTitle != ''"> 
     <xsl:element name="tab"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="substring-after(@ID, '-')"/> 
     </xsl:attribute> 
     <xsl:attribute name="title"> 
      <xsl:value-of select="@componentTitle"/> 
     </xsl:attribute> 
     <xsl:attribute name="url"> 
      <xsl:value-of select="@pageURL"/> 
     </xsl:attribute> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

此前,它工作正常,但现在有需要再改,现在我需要渲染其@Title开始以“T”或“T”以及接下来的3个字符的应该是那些节点例如在上面的xml“航班时刻表”不应该来,我想我只需要再写一个条件在<xsl:if test="@componentTitle != ''">,

请建议!如何做到!

+0

好问题(+1)。查看我的答案,了解简化的单行表达式以及检查字符串是否包含数字的标准方法。 :) – 2010-09-05 14:27:29

+0

好问题(+1)。并看到我更好的单线。 – dolmen 2010-09-09 17:10:19

回答

-1

我想出了下面的解决方案,请建议是否可以!

<xsl:template match="tcm:Item"> 
    <xsl:if test="@componentTitle != '' and (starts-with(translate(@Title, 't', 'T'), 'T')and string(number(substring(@Title,2,3))) != 'NaN')"> 
     <xsl:element name="tab"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="substring-after(@ID, '-')"/> 
     </xsl:attribute> 
     <xsl:attribute name="title"> 
      <xsl:value-of select="@componentTitle"/> 
     </xsl:attribute> 
     <xsl:attribute name="url"> 
      <xsl:value-of select="@pageURL"/> 
     </xsl:attribute> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 

您的所有输入是必需的!

+0

而不是将您的测试放入模板中,您应该在选择节点时在'apply-template'元素中使用它。 – Oded 2010-09-05 07:48:16

+0

@Oded:最好的XSLT风格是“纯粹推送”。不要选择,只是匹配。查看我的解决方案以及我给出的许多其他答案,例如纯推式样式。 – 2010-09-05 14:32:55

+0

'T0.0'是匹配的。看到我的答案,只接受数字。 – dolmen 2010-09-09 12:38:10

0

与XSLT工作只是很偶然,我想出了以下解决方案:

<xsl:if test="@componentTitle != ''"> 
    <xsl:if test="starts-with(@Title,'T') or starts-with(@Title,'t')"> 
    <xsl:if test="string-length(@Title) &gt; 3"> 
     <xsl:if test="string(number(substring(@Title,2,3))) != 'NaN'"> 
... 
     </xsl:if> 
    </xsl:if> 
    </xsl:if> 
</xsl:if> 

我注意到,也有功能,这可以用于测试的第一个字符是lower-case/upper-case一个tT但它们似乎只在XSLT2.0中可用。

+0

非常感谢安德烈为您的时间和解决方案,但是您可以请检查下面的解决方案提出我自己! – 2010-09-05 07:26:08

+0

四个嵌套'if' s !!!!当然可以重构。 – 2010-09-05 14:30:32

1

你应该选择节点要在模板中apply-templates元素上操作:

<xsl:apply-templates select="tcm:Item[@componentTitle != '' 
          and (starts-with(translate(@Title, 't', 'T'), 'T') 
          and string(number(substring(@Title,2,3))) != 'NaN')]"> 

我已经使用了@solution此产生的测试 - 它非常适用的要求(测试here)。

这比选择所有tcm:Item节点并在模板中一次测试一个节点要好。

+0

更好的是纯粹的“推”风格 - 不要选择,只是匹配。 – 2010-09-05 14:28:31

+0

-1因为'T0.0'匹配。 – dolmen 2010-09-09 12:23:37

1

选择逻辑最好放在模板的匹配模式中 - 它也可以稍微简化一下。

<xsl:template match= 
"tcm:Item[contains('tT', substring(@Title,1,1)) 
     and 
      number(substring(@Title,2,3)) 
      =  
      number(substring(@Title,2,3)) 
      ] 
"> 

一个规则要记住:始终测试,如果某些字符串$s代表一个数字 - 是这样的:

number($s) = number($s)

+0

+1用于数字测试和模式匹配消解。 – 2010-09-05 21:34:41

2

这里是一个会做匹配最简单的表达:

translate(substring(@Title, 1, 4), 't12345679', 'T000000000') = 'T000' 

这里是模板:

<xsl:template match=" 
tcm:Item[translate(substring(@Title, 1, 4), 't12345679', 'T000000000') = 'T000' 
and @componentTitle != '' "/> 
+0

+1,因为这是一个通用的模式。即使用translate来进行实现您的业务规则的字符串匹配。简洁而不会难以理解。 – 2012-03-25 16:49:17

相关问题