[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
[Recent Entries]
[Reply To This Message]
Re: Using XSLT to build an index
Subject: Re: Using XSLT to build an index
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Mon, 31 Oct 2011 07:57:30 +0000
|
It's probably better to use xsl:for-each-group for this rather than
distinct-values(), since it retains more context.
You can then do
<xsl:for-each-group select="Text" group-by="tokenize(@data,
$myTokenizingRegex)">
<xsl:for-each select="current-group()">
<xsl:sort select="current-grouping-key()" lang="cz"/>
<Word title="{@title}" ref="{@ref}"><xsl:value-of select="."/></Word>
</xsl:for-each>
</xsl:for-each-group>
Note that xsl:for-each-group puts an element in more than one group if
the group-by expression returns more than one value in its result.
Michael Kay
Saxonica
On 31/10/2011 05:29, Mark wrote:
I have now normalized and isolated every phrase I wish to index into a
few thousand structures similar to:
<Text lang="en" data="Zlutice Hymnal 1558" title="Czech Republic Stamp
664" ref="2010-664.htm"/>
and want to break the @data attribute string into into individual
words associated with its title and ref attributes. How do I use
"distinct-values(tokenize(@data))" to construct a sequence of <Word>
elements from the <Text> element similar to the following? That is, I
don't see how to get at the words returned from
distinct-values(tokenize(@data)) one at a time to do this.
<Word title="Czech Republic Stamp 664" ref="2010-664.htm">Zlutice</Word>
<Word title="Czech Republic Stamp 664" ref="2010-664.htm">Hymnal</Word>
<Word title="Czech Republic Stamp 664" ref="2010-664.htm">1558</Word>
Thanks, Mark
-----Original Message----- From: G. Ken Holman
Sent: Sunday, October 30, 2011 3:07 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: Using XSLT to build an index
At 2011-10-30 14:47 -0700, Mark wrote:
The list archives did not seem to contain an XSLT stylesheet that
could index an XML file, but I may have missed it. Is it practical to
write my own XSLT 2 indexing stylesheet? If so, I have a bilingual
XML file that I want to index.
Where you simply want all words, except your stop
words, collected to automate the index
generation, I've never been successful with
automated indexing myself. For my books I've
authored the components of the index, and then
pointed to those components from within the code.
My assumptions are that I must get rid of the punctuation properly,
then isolate the words, sort them, remove stop words, and so on. To
get started, I need a bit of help. All of the phrases are found in
two attributes: @czech and @eng.
Three questions:
(1) I am aware from MichaelC"b,b"s book that regex expressions may be
used in the replace() function, but I do not know how to write that
regex expression. I would like to remove all the punctuation from a
phrase as follows: for everything except a hyphen [-], replacement
should be with an empty string; the hyphen should be replaced with a
single space.
Simple character removal can be done with
translate() in XSLT 1 or 2 rather than using a regular expression:
translate($inValue,'-,#.$%',' ')
... where the first argument is your input, the
second starts with a "-" and then you put
anything else in there as characters to remove,
the third indicates the hyphen becomes a space and the rest are to be
removed.
(2) I assume that to get rid of extra spaces (if any), I can use a
construct like: normalize-space(replace(@czech, C"b,Ksome regex
expressionC"b,b")).
That will reduce all sequences of white-space characters to a single
space.
(3) I assume that tokenize(normalize-space(replace(@czech, 'some
regex expression'))) will permit me to write out a list of the words
found in those attributes to an XML document. I am not completely
clear as to what tokenize() returns, or how to access that return.
tokenize() returns a sequence. But the input is only a single string.
Actually, you want to turn the expression
inside-out to get a list of words from the entire
document then something along these lines should work:
distinct-values(
(//@czech)/tokenize(translate(normalize-space(.),'-,$%.#',' ')) )
That gives you a sequence of unique words. Can
you work from that in order to do the
hyperlinking, or do you need help there as
well? Remember you will have to do the same
translation when creating your links, so perhaps
you should have a user function:
mark:words(.) as
tokenize(translate(normalize-space($arg),'-,$%.#',' '))
... then use:
(//@czech)/mark:words(.)
... then when creating your links you'll have the
function available to ensure the same tokenizing is done at the point
in time.
I hope this helps.
. . . . . . . . . . Ken
--
Contact us for world-wide XML consulting and instructor-led training
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Google+ profile: https://plus.google.com/116832879756988317389/about
Legal business disclaimers: http://www.CraneSoftwrights.com/legal
|
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format
RSS 2.0 |
|
Atom 0.3 |
|
|