3

I'm attempting to write an XSLT stylesheet that will handle a Dublin Core (XML) cataloging record and create Chicago, APA, and MLA versions of the citation for each book. I've got everything worked out fine except the APA author one. APA's style for authors requires the author's last name (done), comma, first initial (done), any other initials (my stuck place problem).

What I have right now (and sample DC element is below):

<xsl:value-of select="substring-before(dc:creator[1],',')" /><xsl:text>, </xsl:text><xsl:value-of select="substring(substring-after(dc:creator[1],' '),1,1)" /><xsl:for-each select="dc:creator[position()!=1]"><xsl:choose><xsl:when test="position()=last()"><xsl:text>., &amp; </xsl:text></xsl:when><xsl:otherwise>., </xsl:otherwise></xsl:choose><xsl:value-of select="substring-before(.,',')" /><xsl:text>, </xsl:text><xsl:value-of select="substring(substring-after(.,' '),1,1)" /><xsl:if test="position()=last()">.</xsl:if></xsl:for-each> 

For instances of the following format (what out catalog uses):

<dc:creator>Friend, Natasha</dc:creator> 

this works just fine and returns: Friend, N.

But for

<dc:creator>Tolkien, J. R. R.</dc:creator> 

it returns: Tolkien, J.

In a lot of cases it doesn't matter, but there will be cases where it really needs to return authors' middle initial(s), like J.R.R. Tolkien or J.K. Rowling.

So, I need to be able to return the letter that occurs after each space, not just the first instance of a space.

Any ideas?

1 Answer 1

3

I. Here is an easy and natural XSLT 2.0 solution:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/*/*"> <xsl:value-of separator=", " select= "substring-before(., ',') , for $n in tokenize(substring-after(., ','), '\s')[.] return substring($n, 1,1) "/> <xsl:text>&#xA;</xsl:text> </xsl:template> </xsl:stylesheet> 

When this transformation is applied on the following XML document:

<t xmlns:dc="some:dc"> <dc:creator >Friend, Natasha</dc:creator> <dc:creator>Tolkien, J. R. R.</dc:creator> </t> 

the wanted, correct result is produced:

Friend, N Tolkien, J., R., R. 

II. An XSLT 1.0 solution:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/*/*/text()"> <xsl:value-of select="substring-before(., ',')"/> <xsl:call-template name="replaceTokenDelims"> <xsl:with-param name="pStr" select= "concat(normalize-space(substring-after(., ',')), ' ')"/> <xsl:with-param name="pToken" select="' '"/> <xsl:with-param name="pReplacement" select="', '"/> </xsl:call-template> <xsl:text>&#xA;</xsl:text> </xsl:template> <xsl:template name="replaceTokenDelims"> <xsl:param name="pStr"/> <xsl:param name="pToken"/> <xsl:param name="pReplacement"/> <xsl:if test="$pStr"> <xsl:value-of select="$pReplacement"/> <xsl:value-of select= "substring(substring-before($pStr, $pToken), 1, 1)"/> <xsl:call-template name="replaceTokenDelims"> <xsl:with-param name="pStr" select="substring-after($pStr, $pToken)"/> <xsl:with-param name="pToken" select="$pToken"/> <xsl:with-param name="pReplacement" select="$pReplacement"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> 

When this transformation is applied on the same XML document (above), again the same correct result is produced:

Friend, N Tolkien, J., R., R. 
Sign up to request clarification or add additional context in comments.

10 Comments

I'd been using 1.0 since I was more familiar with it, but I'll check that out, thank you. The return looks great except for the , after each, but I'll just take that out.
@Talia: I thaught that , was wanted as the new delimiter. If not what should be the delimiter? I will also provide an XSLT 1.0 solution.
@Talia, Updated the answer with an added XSLT 1.0 solution.
Thank you for the XSLT 1.0 one. I'll experiment tonight/tomorrow with both. The delimiter ", " is wanted after the last name and after the final initial but not after any initials in between. APA style is...complicated. /sigh
@Talia, So, what should be the proper result for Tolkien, J. R. R. ?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.