obdurodon / dh_course

Digital Humanities course site
GNU General Public License v3.0
20 stars 6 forks source link

Using translate() in XSLT #5 #461

Closed EsRessel closed 3 years ago

EsRessel commented 4 years ago

I am attempting to use the translate() function to fix the sort order of the first lines of the sonnets in the table of contents in XSLT Assignment 5. Here is my code that removes apostrophes (inspired by the Michael Kay explanation linked on the assignment):

<xsl:variable name="CXXI" select="//sonnet[@number='CXXI']"/>
<xsl:value-of select="translate($CXXI, '''', '')"/>

This removes the apostrophes but I'm not sure where to go from here.

The apostrophes need to be removed before the sonnets are sorted. It is unable to go directly in the <xsl:apply-templates> element and therefore cannot come directly before <xsl:sort>. However, when I place the variable declaration and translate function statement above the <xsl:apply-templates>, it outputs the entirety of Sonnet CXXI without apostrophes, followed by the sorted table of contents with the first line of Sonnet CXXI still in the first position. Does anyone have suggestions that can point me in the right direction?

djbpitt commented 4 years ago

@EsRessel You’re on the right track. The <xsl:sort> function normally sorts by alphabetical order of the string value, so the leading apostrophe, which sorts before any letters, would be a problem. But <xsl:sort select="translate(., '''', '')"> inside an <xsl:apply-templates> will sort the sonnets or lines (if that’s what you’re applying templates to) by the string value after stripping the apostrophe. The trick is that you don”t want to return the value after stripping (which is what your example above does); you want to use the value after stripping to sort the output, and then return the original value. Does this help?

EsRessel commented 4 years ago

Yep! Rather than sorting with apostrophes at the front, the @select will override the default and tell <xsl:sort> how to sort. Reading from the inside out: the translate function acts on the current context (all of the <sonnet> children that are children of any other element), finds the apostrophes and replaces them with nothing. <xsl:sort> then fires on this modified input.