开发者

XSLT Templates and applying templates

I am very new to XSLT and I am having a hard time understanding some of its concepts.

I have the following XML file:

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <?xml-stylesheet type="text/xsl" href="test.xsl"?>

<Page>
    <Page>
        <Page />
    </Page>
    <Page>
        <Page />
    </Page>
    <Page />
    <Page />
    <Page />
</Page>

And when the following XSL file (test.xsl) is applied:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
 <html>
    <head>
    </head>
    <body>
        <h2>
            <xsl:apply-templates name="PageCount" />
        </h2>
    </body>
 </html>
 </xsl:template>

 <xsl:template match="Page" name="PageCount">
     Page <xsl:value-of select="position()" />
     of <xsl:value-of select="count(/Page/Page)" />

 </xsl:template>
</xsl:stylesheet>

I get the output:

Page 2 of 5

However if I change the "apply-templates" to "call-template" it changes the output to:

Page 1 of 5

Why does this happen?

Also if I add another template:

  <xsl:template match="Page" name="PageCount2">
    Page <xsl:value-of select="position()" />
    of <xsl:value-of select="count(/Page)" />
  </xsl:te开发者_运维技巧mplate>

and use "apply-templates" it seems gives me the output:

Page 2 of 1

This is baffling to me. What is going on?

Thanks in advance.


When you use <xsl:apply-templates/>, it is really short for <xsl:apply-templates select="node()"/> and is being invoked inside of a template match on /, which is the root node of the document and an abstract concept for the top of the file. It's children include the document element (i.e. <Page>), as well as any top-level comments or processing instructions that may be siblings of the document element.

So, when you are "standing" on the root node, the call to <xsl:apply-templates/> will apply templates to /Page, which matches the template that you define. position() is evaluated from the matched context, which is /Page, and returns 2, because it is the second item in the document. The first item is the xml-stylesheet processing instruction. If you were to remove it, then position() would evaluate to 1.

When you use <xsl:call-template name="PageCount"/>, it invokes the same template, but the context does not change when the template is called. You are still "standing" on the root node, so position() evaluates to 1.

The count() always evaluates the same, regardless of the context, because it uses an XPath that starts at the root node. If you were to change it to count(Page/Page) and evaluate relative from the context node, then you would get different values(2 and 5 respectively).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜