在xsl:apply-templates标记中正确地使用xpath作为“选择=”属性

时间:2022-11-28 13:20:16

I am new to xslt and i am getting quite a hard time getting used to its xsl:apply-templates element.Here i have a simple xml file and i wnat to apply XSL style on its elements.I want to select every entry element from my XML file and show the title child of it on the screen.I am extracting the section from my XSL file where lies my confusion.

我是xslt的新手,我很难习惯它的xsl:apply-templates元素。这里我有一个简单的xml文件,我想在它的元素上应用XSL样式。我想从XML文件中选择每个条目元素,并在屏幕上显示它的标题子元素。我正在从我的XSL文件中提取出我的困惑所在的部分。

<xsl:template match='/'>
<html>
  <head>
     <title>my xsl file</title>
  </head>
  <body>
    <h2>my book collection</h2>
      <xsl:apply-templates select='entry'/>
  </body>
</html>
</xsl:template>

In the above snippet in xsl:apply-templates tag if i use select attribute,no content is shown on the screen.But if i remove it everything is fine.My question is why is that ? Am i not supposed to select and match the entry tag.Like the following

在上面xsl:apply-templates标签中的片段中,如果我使用select属性,屏幕上不会显示任何内容。但如果我把它去掉,一切都没问题。我的问题是为什么会这样?我不应该选择和匹配入口标签。像下面的

<xsl:template match='entry'>
   <p>
       <xsl:apply-templates select='title'/>

   </p>
</xsl:template>

here i have to "select" the "title" tag form every entry then have to make a template match for "title" tag.Like the following.Previous snippent selects the title tag and the following snippet matches it and create a h2 tag with its content.Then why we can't do the same thing for entry tag which is the parent of title tag?

在这里,我必须“选择”每个条目的“标题”标签,然后必须为“title”标签做一个模板匹配。像下面。前面的snippent选择title标记,下面的代码片段与之匹配,并使用其内容创建一个h2标记。那么为什么我们不能对title标签的父标签做同样的事情呢?

<xsl:template match='title'>

  <h2 style='color:red;'><xsl:value-of select="."/></h2>

</xsl:template>

FULL code: XML file:

完整代码:XML文件:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='haha.xslt'?>
<book>
   <entry>
       <title>amar boi</title>
       <page>100</page>
   </entry>
   <entry>
       <title>adhunik biggan</title>
       <page>200</page>
   </entry>
   <entry>
       <title>machine design</title>
       <page>1000</page>
   </entry>
</book>

XSL file:

XSL文件:

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

<xsl:template match='/'>
<html>
  <head>
     <title>my xsl file</title>
  </head>
  <body>
    <h2>my book collection</h2>
      <xsl:apply-templates select='entry'/>
  </body>
</html>
</xsl:template>
<xsl:template match='entry'>
   <p>
       <xsl:apply-templates select='title'/>

   </p>
</xsl:template>

<xsl:template match='title'>

  <h2 style='color:red;'><xsl:value-of select="."/></h2>

</xsl:template>


</xsl:stylesheet>

2 个解决方案

#1


3  

In the above snippet in xsl:apply-templates tag if i use select attribute,no content is shown on the screen.But if i remove it everything is fine.My question is why is that ?

在上面xsl:apply-templates标签中的片段中,如果我使用select属性,屏幕上不会显示任何内容。但如果我把它去掉,一切都没问题。我的问题是为什么会这样?

The reason for this is that you are in the context of the / root node (that's what your template matches), and your <xsl:apply-templates/> is selecting "entry" - which is an abbreviation of "child::entry". However, entry is not a child of /, so your expression selects nothing.

这是因为您处于/根节点的上下文中(这是您的模板匹配的),并且您的 正在选择“entry”—这是“child::entry”的缩写。然而,条目不是/的子元素,所以表达式什么都不选择。

If you remove the selection, then templates are applied to nodes that are children of the current node (book in your example). The built-in template rule then applies templates to the children of book and that is how your template matching entry is eventually applied.

如果删除所选内容,那么模板将应用于当前节点的子节点(在示例中为book)。然后,内置的模板规则将模板应用到book的子目录中,这就是最终应用模板匹配条目的方式。

You could avoid this problem simply by changing your first template's start-tag to:

只需将第一个模板的开始标记更改为:

<xsl:template match='/book'>

#2


3  

The root node / is not the same as the document element /* (in your case /book).

根节点/与文档元素/*(在您的情况/书中)不一样。

In your template matching the root node (xsl:template match="/"), you are using xsl:apply-templates select="entry"/>, which is equivalent to /entry and happens to select nothing.

在与根节点匹配的模板中(xsl:template match="/"),您使用的是xsl:apply-templates select="entry"/>,这相当于/输入,碰巧没有选择。

If you want to apply-templates to the entry elements, then you could change the first template to match the document element(as @michael.hor257k recommends), or you could adjust the XPath for the apply-templates in the root node template to be: xsl:apply-templates select="book/entry", or even */entry"

如果希望将模板应用到条目元素,那么可以更改第一个模板以匹配文档元素(如@michael)。hor257k建议),或者您可以调整根节点模板中的apply模板的XPath: xsl:apply-templates select=“book/entry”,甚至是*/entry。

Complete example:

完整的例子:

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

    <xsl:template match='/'>
        <html>
            <head>
                <title>my xsl file</title>
            </head>
            <body>
                <h2>my book collection</h2>
                <xsl:apply-templates select='book/entry'/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match='entry'>
        <p>
            <xsl:apply-templates select='title'/>      
        </p>
    </xsl:template>

    <xsl:template match="title">
        <h2 style="color:red;">
            <xsl:value-of select="."/>
        </h2>
    </xsl:template>

</xsl:stylesheet>

#1


3  

In the above snippet in xsl:apply-templates tag if i use select attribute,no content is shown on the screen.But if i remove it everything is fine.My question is why is that ?

在上面xsl:apply-templates标签中的片段中,如果我使用select属性,屏幕上不会显示任何内容。但如果我把它去掉,一切都没问题。我的问题是为什么会这样?

The reason for this is that you are in the context of the / root node (that's what your template matches), and your <xsl:apply-templates/> is selecting "entry" - which is an abbreviation of "child::entry". However, entry is not a child of /, so your expression selects nothing.

这是因为您处于/根节点的上下文中(这是您的模板匹配的),并且您的 正在选择“entry”—这是“child::entry”的缩写。然而,条目不是/的子元素,所以表达式什么都不选择。

If you remove the selection, then templates are applied to nodes that are children of the current node (book in your example). The built-in template rule then applies templates to the children of book and that is how your template matching entry is eventually applied.

如果删除所选内容,那么模板将应用于当前节点的子节点(在示例中为book)。然后,内置的模板规则将模板应用到book的子目录中,这就是最终应用模板匹配条目的方式。

You could avoid this problem simply by changing your first template's start-tag to:

只需将第一个模板的开始标记更改为:

<xsl:template match='/book'>

#2


3  

The root node / is not the same as the document element /* (in your case /book).

根节点/与文档元素/*(在您的情况/书中)不一样。

In your template matching the root node (xsl:template match="/"), you are using xsl:apply-templates select="entry"/>, which is equivalent to /entry and happens to select nothing.

在与根节点匹配的模板中(xsl:template match="/"),您使用的是xsl:apply-templates select="entry"/>,这相当于/输入,碰巧没有选择。

If you want to apply-templates to the entry elements, then you could change the first template to match the document element(as @michael.hor257k recommends), or you could adjust the XPath for the apply-templates in the root node template to be: xsl:apply-templates select="book/entry", or even */entry"

如果希望将模板应用到条目元素,那么可以更改第一个模板以匹配文档元素(如@michael)。hor257k建议),或者您可以调整根节点模板中的apply模板的XPath: xsl:apply-templates select=“book/entry”,甚至是*/entry。

Complete example:

完整的例子:

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

    <xsl:template match='/'>
        <html>
            <head>
                <title>my xsl file</title>
            </head>
            <body>
                <h2>my book collection</h2>
                <xsl:apply-templates select='book/entry'/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match='entry'>
        <p>
            <xsl:apply-templates select='title'/>      
        </p>
    </xsl:template>

    <xsl:template match="title">
        <h2 style="color:red;">
            <xsl:value-of select="."/>
        </h2>
    </xsl:template>

</xsl:stylesheet>