使用 xslt 解析名称
Parse names using xslt
我正在尝试编写一个 XSLT 样式表来处理作者姓名并将其格式化为 Google 学术搜索结果中显示的格式。
我的目标是遵循上图(突出显示)中显示的名称格式,例如,如果我有这个 xml:
<names>
<author>Naylor, Rosamond L.</author>
<author>Goldburg, Rebecca J.</author>
<author>Primavera, Jurgenne H.</author>
<author>Kautsky, Nils</author>
</names>
名字并不总是"Last name, First name MI."格式,也可以只是姓氏和首字母,像这样:
<names>
<author>Naylor, R.L.</author>
<author>Goldburg, R. J.</author>
<author>Primavera, J.H.</author>
<author>Kautsky, Nils</author>
</names>
如果您问我到目前为止尝试了什么,我会 post 将其作为更新。我仍在修改我用于 question 的代码,我很久以前就在这里 post 编辑过。
提前致谢。
鉴于:
XML
<names>
<author>Naylor, R.L.</author>
<author>Goldburg, R. J.</author>
<author>Primavera, J.H.</author>
<author>Kautsky, Nils</author>
</names>
以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template match="names">
<xsl:for-each select="author">
<xsl:variable name="first-names" select="substring-after(., ', ')" />
<xsl:value-of select="translate($first-names, translate($first-names, $upper-case, ''), '')"/>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(., ', ')" />
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
将return:
RL Naylor, RJ Goldburg, JH Primavera, N Kautsky
警告:
XSLT 1.0 中没有 upper-case() 函数。上述方法仅适用于明确枚举的大写字符。如果文本包含其他字符(例如带有变音符号的字符),它将失败。
如果这是一个问题,最好使用类似的东西:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="names">
<xsl:for-each select="author">
<xsl:for-each select="str:tokenize(substring-after(., ', '),' .')">
<xsl:value-of select="substring(., 1, 1)" />
</xsl:for-each>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(., ', ')" />
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
假设您的处理器支持 EXSLT str:tokenize() 函数(如果不支持,您将必须调用命名的递归模板来进行标记化)。
我正在尝试编写一个 XSLT 样式表来处理作者姓名并将其格式化为 Google 学术搜索结果中显示的格式。
我的目标是遵循上图(突出显示)中显示的名称格式,例如,如果我有这个 xml:
<names>
<author>Naylor, Rosamond L.</author>
<author>Goldburg, Rebecca J.</author>
<author>Primavera, Jurgenne H.</author>
<author>Kautsky, Nils</author>
</names>
名字并不总是"Last name, First name MI."格式,也可以只是姓氏和首字母,像这样:
<names>
<author>Naylor, R.L.</author>
<author>Goldburg, R. J.</author>
<author>Primavera, J.H.</author>
<author>Kautsky, Nils</author>
</names>
如果您问我到目前为止尝试了什么,我会 post 将其作为更新。我仍在修改我用于 question 的代码,我很久以前就在这里 post 编辑过。
提前致谢。
鉴于:
XML
<names>
<author>Naylor, R.L.</author>
<author>Goldburg, R. J.</author>
<author>Primavera, J.H.</author>
<author>Kautsky, Nils</author>
</names>
以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template match="names">
<xsl:for-each select="author">
<xsl:variable name="first-names" select="substring-after(., ', ')" />
<xsl:value-of select="translate($first-names, translate($first-names, $upper-case, ''), '')"/>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(., ', ')" />
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
将return:
RL Naylor, RJ Goldburg, JH Primavera, N Kautsky
警告:
XSLT 1.0 中没有 upper-case() 函数。上述方法仅适用于明确枚举的大写字符。如果文本包含其他字符(例如带有变音符号的字符),它将失败。
如果这是一个问题,最好使用类似的东西:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="names">
<xsl:for-each select="author">
<xsl:for-each select="str:tokenize(substring-after(., ', '),' .')">
<xsl:value-of select="substring(., 1, 1)" />
</xsl:for-each>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(., ', ')" />
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
假设您的处理器支持 EXSLT str:tokenize() 函数(如果不支持,您将必须调用命名的递归模板来进行标记化)。