我正在尝试编写一个XSLT样式表来处理Dublin Core(XML)编目记录,并为每本书创建引用的芝加哥,APA和MLA版本。除了APA的作者之外,我的一切都很好。 APA的作者风格需要作者的姓氏(完成),逗号,第一个首字母(已完成),任何其他首字母(我的卡住地点问题)。
我现在所拥有的(以及样本DC元素如下):
<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>., & </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>
对于以下格式的实例(目录使用的内容):
<dc:creator>Friend, Natasha</dc:creator>
这很好用并返回:Friend, N.
但是
<dc:creator>Tolkien, J. R. R.</dc:creator>
它返回:Tolkien, J.
在很多情况下,这并不重要,但有时候确实需要返回作者的中间名首字母,例如J.R.R. Tolkien
或J.K. Rowling
。
所以,我需要能够返回每个空间之后出现的字母,而不仅仅是空格的第一个实例。
有什么想法吗?
答案 0 :(得分:3)
<强>予。这是一个简单而自然的XSLT 2.0解决方案:
<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>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
对以下XML文档应用此转换时:
<t xmlns:dc="some:dc">
<dc:creator >Friend, Natasha</dc:creator>
<dc:creator>Tolkien, J. R. R.</dc:creator>
</t>
产生了想要的正确结果:
Friend, N
Tolkien, J., R., R.
<强> II。 XSLT 1.0解决方案:
<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>
</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>
当在同一个XML文档(上面)上应用此转换时,会再次生成相同的正确结果:
Friend, N
Tolkien, J., R., R.