2011-11-16 71 views
2

我正在使用PHP/XSL转换XML文档。我正在寻找关键字值。我想添加分页,所以我没有返回所有的搜索结果。我可以用单独的xsl文件做到这一点,但如果可以的话,我想加入它们。如何返回搜索结果,然后应用分页?例如。XSL应用多个模板

寻呼

... 
<xsl:if test="position() &gt; $start and position() &lt; $end"> 
... 

Search.xsl

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

<xsl:template match="/*"> 
<items> 
<xsl:attribute name="count"><xsl:value-of select="count(//item)"/></xsl:attribute> 
<xsl:apply-templates select="//item"> 
    <xsl:sort select="*[name()=$sortBy]" order="{$order}" data-type="{$type}" /> 
</xsl:apply-templates> 
</items> 
</xsl:template> 

<xsl:template match="//item"> 
    <xsl:choose> 
     <xsl:when test="contains(
       translate(title, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
        'abcdefghijklmnopqrstuvwxyz'), $keyword) 
        or contains(translate(content, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
        'abcdefghijklmnopqrstuvwxyz'), $keyword)"> 
      <item> 
       <title><xsl:value-of select="title"/></title> 
       <content><xsl:value-of select="content"/></content> 
       <date><xsl:value-of select="date"/></date> 
       <author><xsl:value-of select="author"/></author> 
       <uri><xsl:value-of select="uri"/></uri> 
       <division><xsl:value-of select="division"/></division> 
      </item> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

最终解决方案使用XSL可变和节点集()

需要做一些更多的检查,但我很确定这工作正常。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common"> 
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" encoding="UTF-8"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="searchResults"> 
    <xsl:apply-templates select="//item"> 
     <xsl:sort select="*[name()=$sortBy]" order="{$order}" data-type="{$type}" /> 
    </xsl:apply-templates> 
</xsl:variable> 

<xsl:template match="//item"> 
    <xsl:choose> 
     <xsl:when test="contains(translate(title, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), $keyword) or contains(translate(content, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), $keyword)"> 
      <item> 
       <title><xsl:value-of select="title"/></title> 
       <content><xsl:value-of select="content"/></content> 
       <date><xsl:value-of select="date"/></date> 
       <author><xsl:value-of select="author"/></author> 
       <uri><xsl:value-of select="uri"/></uri> 
       <division><xsl:value-of select="division"/></division> 
      </item> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="//item" mode="paging"> 
    <xsl:choose> 
     <xsl:when test="position() &gt; $start and position() &lt; $end"> 
      <item> 
       <title><xsl:value-of select="title"/></title> 
       <content><xsl:value-of select="content"/></content> 
       <date><xsl:value-of select="date"/></date> 
       <author><xsl:value-of select="author"/></author> 
       <uri><xsl:value-of select="uri"/></uri> 
       <division><xsl:value-of select="division"/></division> 
      </item> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="/*"> 
    <items> 
     <xsl:attribute name="count"><xsl:value-of select="count(//item)"/></xsl:attribute> 
     <xsl:apply-templates select="exslt:node-set($searchResults)/*" mode="paging" /> 
    </items> 
</xsl:template> 

回答

0

阅读XSLTmodes

然后在这两种情况下使用:

<xsl:apply-templates mode="search" select="someExpression"> 
<!-- <xsl:with-param> children if necessary --> 
<!-- <xsl:sort> children if necessary --> 
</xsl:apply-templates> 

也:

<xsl:apply-templates mode="paging" select="someExpression"> 
<!-- <xsl:with-param> children if necessary --> 
<!-- <xsl:sort> children if necessary --> 
</xsl:apply-templates> 

当然,你必须有tempaltes在上述各模式。

+0

谢谢迪米特,但我可以选择相同的节点,例如在两个模板中选择=“// item”? – rossjha

+0

@rossjha:选择模板的节点首先由''指令确定,然后模板的匹配模式必须与节点匹配,并且必须具有最高的导入优先级和优先级。简单的答案是模板将被选中执行,但不能同时使用单个''。您需要有两个单独的''指令:''和'' –

+0

抱歉没有得到这个。你能举个例子吗?尝试添加''和''工作 – rossjha

0

我认为这是没有办法在单一转换中应用不同的模板。因此,尝试添加分页XPath搜索的XPath:

<xsl:when test="contains(
      translate(title, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
       'abcdefghijklmnopqrstuvwxyz'), $keyword) 
       or contains(translate(content, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
       'abcdefghijklmnopqrstuvwxyz'), $keyword) 
       and 
       position() &gt; $start and position() &lt; $end"> 
0

这种感觉对我来说,你应该转型分为两个阶段,一个做搜索和一个做传呼的情况下。

您可以编写一个执行两个转换的管道作为单独的样式表,或者(在exslt:node-set()的帮助下),您可以在单个样式表中将其保存在临时变量中。我推荐两种样式表 - 它使代码更具可读性和可重用性。

+0

嗨你能给我一个写一个管道的例子吗?听起来很有趣。 – rossjha