position()=1 working correctly, but not position()

2019-07-09 03:20发布

问题:

I'm new to XSLT, and I'm carrying out a few tests using w3schools "Try it yourself" pages. I'm using the following demo:

http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=tryxsl_choose

This contains the following line:

<xsl:for-each select="catalog/cd">

I'm testing filtering the HTML rendered by position() but I'm having issues when using the < operand.


I've tried the following:

<xsl:for-each select="catalog/cd[position()=1]">

And this returns the first item from the XML data (as expected).


I then tried:

<xsl:for-each select="catalog/cd[position()<5]">

I was expecting this to return the first 4 items, but instead I get no results.

My guess is that perhaps position()=1 is doing a string comparison, which is why it returns the first item, but it cannot understand position()<5 as a string cannot be compared in this way?

Why is this happening, and what would be the correct syntax to get the results I wish to achieve?


Update: After reading @joocer's response, and testing this myself, using the > operand does work, for the opposite result:

<xsl:for-each select="catalog/cd[(position()>5)]">

回答1:

Even inside quotes, you must type < as &lt; so it won't be confused for the start of an element tag. I think this was done to make it easier for tolerant parsers to recover from errors and streaming parsers skip content faster. They can always look for < outside CDATA and know that is an element start or end tag.



回答2:

It looks very much like a bug in the version of libxslt that w3schools is using.



回答3:

I don't know why, but inverting the condition works, so instead of looking for less than 5, look for not more than 4

<xsl:for-each select="catalog/cd[not(position()>4)]">


标签: xslt foreach