使用 XSLT 在字符串/子字符串中的每个实例之后进行选择 [英] Using XSLT to select after EACH instance in a string/substring

查看:27
本文介绍了使用 XSLT 在字符串/子字符串中的每个实例之后进行选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个 XSLT 样式表,该样式表将处理都柏林核心 (XML) 编目记录并为每本书创建芝加哥、APA 和 MLA 版本的引文.除了 APA 作者之外,我一切都很好.APA 的作者风格需要作者的姓氏(完成)、逗号、第一个首字母(完成)、任何其他首字母(我的卡住位置问题).

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).

我现在拥有的(和示例 DC 元素如下):

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>

这很好用并返回:Friend, N.

但是为了

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

它返回:Tolkien, J.

在很多情况下这无关紧要,但有些情况下确实需要返回作者的中间名首字母,例如 J.R.R.托尔金J.K.罗琳.

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.

有什么想法吗?

推荐答案

I.这是一个简单而自然的 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>&#xA;</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.

<小时>

二.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>&#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>

当这个转换应用于同一个 XML 文档(上图)时,同样会产生相同的正确结果:

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

这篇关于使用 XSLT 在字符串/子字符串中的每个实例之后进行选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆