[Home] [By Thread] [By Date] [Recent Entries]
Hi Wayne,
The problems here are in your XPath expressions. They're not doing quite what you expect. Let's look at that for-each select first:
The XPath:
Truck[not(VINModelYearName/preceding::Truck/VINModelYearName)]
| Truck[not(VINModelName/preceding::Truck/VINModelName)]translates into (sort-of) English as "All Truck element children that do not have a VINModelYearName child that are preceded (somewhere in the document) by a Truck element with a VINModelYearName child, ALONG WITH all Truck element children that do not have a VINModelName child that are preceded (somewhere in the document) by a Truck element with a VINModelName child" I don't think you want this. Something like (let's just look at the first half)
Truck[not(VINModelYearName = preceding::Truck/VINModelYearName)]
is closer, it says"All Truck element children that do not have a VINModelYearName child (whose string value is) equal to the VINModelYearName child of a preceding Truck element" But even that's not right. Putting this together with a similar second term, you'd in effect be getting all Truck children with a new VINModelYearName along with all Truck children with a new VINModelName -- but this isn't the list you want. (What if you encountered a new Truck, but you'd had both its model name and its model year before, just not together -- you'd miss it.) Similarly, the XPath in the count expression will be wrong. I think what you're missing is that XPath expressions are evaluated with respect to a context node. This is making your logic hard to construct. I know the count part is wrong. I think I would put whatever pattern I use in my for-each in my count to return the same set of results to count. Nope: the context node has changed, so the expression won't return the same thing. I'm not sure though, because basically what I'm trying to do is create nodes on the fly matching a particular pattern. The pattern can change, because I want it for all the years, and for any Model (Which I could make a list of, but it would be quite long). Well, sort of. Basically, yours is a grouping problem. (Hint: look up "grouping" in the XSL FAQ.) And it admits of a nice elegant solution if you use the XSLT idiom known as "Muenchian grouping", using a key expression. In fact, your analysis hints at this solution, in stipulating that you want to find nodes based on "a particular pattern": that's what the key will let you do. So, a key declaration such as <xsl:key name="TruckModelYear" match="Truck" use="concat(VINModelName, VINModelYearName)"/> Creates a key you can use to retrieve your trucks. Each Truck is assigned a "TruckModelYear" key whose value is the combination of its VINModelName AND VINModelYearName children. Then, the instruction <xsl:for-each select="Truck[generate-id() = generate-id(key('TruckModelYear', concat(VINModelName, VinModelYearName)))[1]]"> [nb: untested] iterates over your Truck element children -- except it skips those that are not the first that match any given key. [Explanation: it keeps only those whose generated ID matches a generated ID for the first node (in document order) in the set of nodes (Trucks) with the same key value, i.e. same VINModelName and VINModelYearName.] Then inside the for-each, the expression count(key('TruckModelYear', concat(VINModelName, VinModelYearName))) will count the number of nodes matched by the key of the current Truck, that is, the number of Trucks that have the same key as the present Truck (the context node). This is an advanced answer, I know ... but it's neater and cleaner than writing the (fancy and cumbersome) XPath to do it by brute force. Hope that helps! (and folks, please check my logic), Wendell At 07:42 PM 3/14/01, you wrote: I'm rather new to XSL (Few months) and am running across a little problem, hoping someone here can help me. Thanks for your time.
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|

Cart



