Subject: Re: How to remove duplicates nodes? From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Sat, 26 Aug 2000 09:29:05 +0100 |
Joel, >I don't believe I can use the 'key' trick since the Context element >is throughout my XML and I only want to do this duplicate analysis >from within a particular rule mapping element. This does add an extra factor into using the Muenchian Method for getting unique nodes. [This email assumes familiarity with the general method - look at http://www.jenitennison.com/xslt/grouping/ for more details.] There are two ways that you can do it. The first is to declare the key in the normal way: you're interested in Context elements, and the unique thing about the Context element is (I think?) the @objectID of the ObjectReference that it holds: <xsl:key name="contexts" match="Context" use="ObjectReference/@objectID" /> This means that with key('contexts', $objectID) you will get all the Contexts in the source that have that particular ObjectReference/@objectID. If you know what RuleMapping you're interested in, you can filter those nodes in terms of that RuleMapping. So, within a template matching RuleMapping elements, if you set a variable to hold the id of the RuleMapping: <xsl:variable name="rule-mapping" select="@id" /> You can then filter the Contexts returned by the key (using a predicate) to give only those Contexts that have that RuleMapping as an ancestor: key('contexts', $objectID)[ancestor::RuleMapping[@id = $rule-mapping]] So this XPath will give all the Contexts within that particular RuleMapping that have that particular ObjectReference/@objectID. Slotting that in to the usual Muenchian solution, you get: <xsl:template match="RuleMapping"> <xsl:variable name="rule-mapping" select="@id" /> Rule Mapping: <xsl:value-of select="@name" /> Unique Contexts: <xsl:copy-of select="Rule/RHS/Context[generate-id() = generate-id(key('contexts', ObjectReference/@objectID)[ancestor::RuleMapping[@id = $rule-mapping]][1])]" /> </xsl:template> Filtering the results of the key() function to get only those returned by it that meet a certain criteria, is a good general solution. It's especially useful when you want a dynamic way of filtering the results of the key, such as a keyword passed in as a parameter. The second method, which may be better in your case, is to create a key with key values that hold information both about the ObjectReference/@objectID *and* about the RuleMapping that the Context is within. You can do this by concatenating the two pieces of information (with an appropriate separator) to give the key value: <xsl:key name="contexts" match="Context" use="concat(ancestor::RuleMapping/@id, '::', ObjectReference/@objectID)" /> You can then index into the key using a value constructed in the same way, giving the template: <xsl:template match="RuleMapping"> <xsl:variable name="rule-mapping" select="@id" /> Rule Mapping: <xsl:value-of select="@name" /> Unique Contexts: <xsl:copy-of select="Rule/RHS/Context[generate-id() = generate-id(key('contexts', concat($rule-mapping, '::', ObjectReference/@objectID))[1])]" /> </xsl:template> Both of these methods give the results that you're after in both SAXON and Xalan. I hope that this helps, Jeni Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: How to remove duplicates nodes?, Joel Riedesel | Thread | Re: How to remove duplicates nodes?, Joel Riedesel |
RE: The XSL-List Digest V3 #192, Mike Van Riper | Date | Re: How to remove duplicates nodes?, Joel Riedesel |
Month |