XSLT组列表的一部分

时间:2012-08-13 14:21:10

标签: xml xslt xpath

我正在努力将列表的某些部分转换为一个组。

说我有这样的清单:

<table>
    <tr>
        <td>One</td>
    </tr>
    <tr>
        <td>Two</td>
    </tr>
    <tr>
        <td><a href="#">Three</a></td>
    </tr>
    <tr>
        <td><a href="#">Four</a></td>
    </tr>
    <tr>
        <td><a href="#">Five</a></td>
    </tr>

    <tr>
        <td>Six</td>
    </tr>
</table>

并希望将其转换为

<p>One</p>
<p>Two</p>
<div class="group">
    <a href="#">Three</a>
    <a href="#">Four</a>
    <a href="#">Five</a>
</div>
<p>Six</p>

我不知道如何实现这一目标。有什么建议吗?

修改 有这样的东西会很有帮助:

<xsl:template match="td[a and ( preceding-sibling::td/a or following-sibling::td/a )]">
    <div class="group"> <!-- this has to be called one time !! -->
        <xsl:for-each select=".//a">
            <xsl:apply-templates select="."/>
        </xsl:for-each>
    </div>
</xsl:template>

我的方法是括号应该将所有匹配分组到模板的一次执行,这样只创建一个分组div。

4 个答案:

答案 0 :(得分:0)

你可以用这样的东西达到目标     

    <xsl:template match="/">
        <xsl:apply-templates select="//tr/td"/>
        <div class="group">
            <xsl:apply-templates select="//td/a"/>
        </div>
    </xsl:template>

    <xsl:template match="//tr/td"> 
        <p><xsl:value-of select="text()"/></p>
    </xsl:template>

    <xsl:template match="//td/a"> 
        <a href="#"><xsl:value-of select="text()"/></a>
    </xsl:template>

编辑:代码解析器删除了一个重要的代码:/现在好了

希望这可以提供帮助

此致

答案 1 :(得分:0)

这个XSLT 1.0样式表...

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

<xsl:template match="/">
 <root>
   <xsl:apply-templates select="*/tr[not(td/a) or not(preceding-sibling::tr/td/a)]" />
 </root>  
</xsl:template>

<xsl:template match="tr[not(td/a)]" priority="0.6">
 <p>
   <xsl:copy-of select="td/@* | td/node()" /> 
 </p>  
</xsl:template>

<xsl:template match="tr[td]">
 <div class="group">
   <xsl:copy-of select="
    td/@* | td/node() | 
    following-sibling::tr[
        preceding-sibling::tr[not(preceding-sibling::tr/td/a)][1]
     ]/td/node()" /> 
 </div>
</xsl:template>

</xsl:stylesheet>

...会将您的样本输入转换为...

<root>
  <p>One</p>
  <p>Two</p>
  <div class="group">
    <a href="#">Three</a>
    <a href="#">Four</a>
    <a href="#">Five</a>
  </div>
</root>

答案 2 :(得分:0)

好吧,我自己找到了一个适合我需求的解决方案:

<xsl:template match="tr[td/a and following-sibling::tr/td/a][1]">
    <div class="list">
        <xsl:apply-templates select=".//a | following-sibling::tr//a"/>
    </div>
</xsl:template>
<xsl:template match="td[p/a]"/>

感谢您的帮助。

答案 3 :(得分:0)

此转换(没有任何xsl:apply-templates指令):

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

 <xsl:template match="tr/td/text()">
     <p><xsl:value-of select="."/></p>
 </xsl:template>
 <xsl:template match="tr[td[a]][1]">
  <div class="group">
   <xsl:copy-of select="../tr[td[a]]/td/a"/>
  </div>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

应用于提供的XML文档时:

<table>
    <tr>
        <td>One</td>
    </tr>
    <tr>
        <td>Two</td>
    </tr>
    <tr>
        <td>
            <a href="#">Three</a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#">Four</a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#">Five</a>
        </td>
    </tr>
    <tr>
        <td>Six</td>
    </tr>
</table>

生成想要的正确结果

<p>One</p>
<p>Two</p>
<div class="group">
   <a href="#">Three</a>
   <a href="#">Four</a>
   <a href="#">Five</a>
</div>
<p>Six</p>