跳转到使用XSLT

时间:2011-08-31 14:02:46

标签: xml xslt xpath

我从第三方获取XML文档(因此我无法更改),其中包含大约1000条记录。我正在使用XSLT翻译它,一次只显示用户50条记录。我可以通过检查位置来控制显示哪些记录,例如

xsl:if test="not(position() < 101)"

xsl:if test="position() < 150"

用户更愿意跳转到某个值而不是逐页滚动,直到找到它为止。其余的记录仍应在跳转到值后显示,因此我不想检查完全匹配。我最初认为我可以进行字符串比较,例如

xsl:if test="@key >= 'jumpto'"

但1.0不支持此功能。任何想法如何实现我想要的东西?

XML非常大,可以发布,数据是保密的。但是想象一下它是一个简单的XML文件,只有一个名称,例如

<contacts>
    <name>alan</name>
    <name>brad</name>
    <name>chad</name>
    <name>dave</name>
    <name>eric</name>
</contacts>

我想只显示从dave开始的数据,我可以将dave传递给XSL文档。

3 个答案:

答案 0 :(得分:2)

XSLT:

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

  <xsl:param name="p">dave</xsl:param>

  <xsl:template match="contacts">
    <out>
      <xsl:apply-templates 
        select="name[. = $p] | name[. = $p]/following-sibling::name"/>
    </out>
  </xsl:template>

  <xsl:template match="name">
    <xsl:copy-of select="."/>
  </xsl:template>

</xsl:stylesheet>

输出:

<out>
  <name>dave</name>
  <name>eric</name>
</out>

答案 1 :(得分:0)

以下转换

  • 使用身份规则按原样复制所有内容(我们可能会在此处避免,但我怀疑您的输入要复杂得多)。
  • 会覆盖联系人元素并仅保留所需的名称节点(具有给定$onward的节点或前一个兄弟名称的任何节点具有给定的$onward

[XSLT 1.0]

 <xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="onward" select="'dave'"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" /> 
        </xsl:copy>
    </xsl:template>

    <xsl:template match="contacts">
        <xsl:copy>
            <xsl:apply-templates select="@* | 
                name[.=$onward or preceding-sibling::name=$onward]"/>
        </xsl:copy> 
    </xsl:template>

</xsl:stylesheet>

默认情况下($onward='dave')会产生:

<contacts>
   <name>dave</name>
   <name>eric</name>
</contacts>

答案 2 :(得分:0)

我认为你需要这样的东西(我假设name已被排序,你想要显示从第一个开始的所有name元素,其值大于或等于{ {1}}):

'dave'

在提供的XML文档上应用此转换时

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

 <my:Start>dave</my:Start>

 <xsl:param name="pStart" select="document('')/*/my:Start"/>

 <xsl:template match="name">
  <xsl:variable name="vThis" select="."/>

  <xsl:for-each select=". | $pStart">
   <xsl:sort/>

   <xsl:if test=
    "position() = 2 and . = $vThis">
    <xsl:copy-of select="$vThis"/>
   </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

产生了想要的正确结果

<contacts>
    <name>alan</name>
    <name>brad</name>
    <name>chad</name>
    <name>dave</name>
    <name>eric</name>
</contacts>

如果转化适用于此XML文档(请注意:没有值为<name>dave</name> <name>eric</name> 的{​​{1}}):

name

再次生成正确的结果 - 每个'dave'的值大于或等于<contacts> <name>alan</name> <name>brad</name> <name>chad</name> <name>dave2</name> <name>eric</name> </contacts> -

name

<强>解释

这里我展示了一个“穷人的XPath 1.0 + XSLT 1.0字符串比较实现。”

对包含两个字符串的节点进行排序。然后,第二个位置的节点的字符串值大于或等于第一个位置的节点的字符串值。