Subject: Re: How to remove duplicates nodes? From: Joel Riedesel <jriedese@xxxxxxxxx> Date: Sat, 26 Aug 2000 06:20:58 -0600 |
This looks nice, but it's actually a bit more complex than that. You've provided some general guidelines which I think I can work with when I tackle this again. The additional complexity comes from what a Context really is. It is a list of ObjectReference elements (a kind of path, if you will). And it is not a valid assumption that the @objectID of an ObjectReference is the unique element of a Context (unfortunately). The only way to compute a unique value of a Context (almost a hashcode if you will) is by looking at all the ObjectReference elements of the Context and concatenating all their attributes together (perhaps by including spaces): @objectID, @attributeGroupID, @instanceID, and @attributeID. By computing that correct unique hash for a context, I can then continue along with the pattern you provided here to remove duplicates using the Muenchian Method (which I had studied before I sent my node - but I didn't think of these more complex key generation methods - thanks!). Your help is much appreciated, thanks a bunch. Joel Jeni Tennison wrote: > > 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/ -- Joel Riedesel Jnana Technologies Corporation mailto:jriedese@xxxxxxxxx XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: How to remove duplicates nodes?, Jeni Tennison | Thread | Re: How to remove duplicates nodes?, Jeni Tennison |
Re: How to remove duplicates nodes?, Jeni Tennison | Date | Re: How to remove duplicates nodes?, Jeni Tennison |
Month |