Xslt 在非文本输出中追加重复字符串的计数

Xslt 在非文本输出中追加重复字符串的计数,xslt,w3c,bibtex,Xslt,W3c,Bibtex,我正在使用生成bibtex文件,但不幸的是,它正在为同一年的论文生成重复的作者密钥 琼斯:2012 琼斯:2012 问题模板在中命名为bibtex label 如何添加每个作者、每年的计数值,使bibtex标签看起来像这样: 琼斯:2012a 琼斯:2012b 我找不到做这类事情的好资源,特别是对于非xml输出 示例输入(来自): 期望输出: @TechReport{LeHors:1998a, author = {Arnaud Le Hors and Scott Isaacs and

我正在使用生成bibtex文件,但不幸的是,它正在为同一年的论文生成重复的作者密钥

  • 琼斯:2012
  • 琼斯:2012
问题模板在中命名为
bibtex label

如何添加每个作者、每年的计数值,使bibtex标签看起来像这样:

  • 琼斯:2012a
  • 琼斯:2012b
我找不到做这类事情的好资源,特别是对于非xml输出

示例输入(来自):

期望输出:

@TechReport{LeHors:1998a,
  author = {Arnaud Le Hors and Scott Isaacs and Steve Byrne and Mike Champion and Gavin Nicol and Lauren Wood and Ian Jacobs and Robert Sutor and Jonathan Robie and Chris Wilson and Vidur Apparao},
  title  = {{Document Object Model (DOM) Level 1}},
  note = {\url{http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001}. Latest version available at \url{http://www.w3.org/TR/REC-DOM-Level-1}},
  year = {1998},
  month = nov,
  bibsource = "http://www.w3.org/2002/01/tr-automation/tr.rdf",
  type = "Recommendation",
  institution = "W3C",
}

@TechReport{LeHors:1998b,
  author = {Arnaud Le Hors and Ian Jacobs and David Raggett},
  title  = {{HTML 4.0 Specification}},
  note = {\url{http://www.w3.org/TR/1998/REC-html40-19980424}. Latest version available at \url{http://www.w3.org/TR/html40}},
  year = {1998},
  month = apr,
  bibsource = "http://www.w3.org/2002/01/tr-automation/tr.rdf",
  type = "Recommendation",
  institution = "W3C",
}

首先,为了简化
translate
函数的safe姓氏函数,可以在XSLT顶部定义两个变量,如下所示

<xsl:variable name="nameIn" 
   select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.- 0123456789ñÑçÇáéíóúÃÉÃÓÚäëïöüÄËÃÖÜ'" />
<xsl:variable name="nameOut" 
   select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

这将允许您编写可读性更强的代码来获取格式化的姓氏

<xsl:variable name="safeSurname" select="translate($surname, $nameIn, $nameOut)" />

当您看到生成后缀的代码时,就会更加清楚,可以使用xsl:number函数来计算具有匹配年份和姓氏的前兄弟姐妹的数量。请注意使用format属性输出字母而不是数字:

<xsl:number 
   value="count(preceding-sibling::rec:REC
      [substring-before(dc:date/text(), '-') = $date]
      [translate(substring-after(rec:editor[1]/contact:fullName, ' '), $nameIn, $nameOut) = $safeSurname]
   ) + 1" 
   format="a"/>

在此代码中,$date是当前REC元素的年份

这是bibtex标签的完整匹配模板。注意:我已使用模式bibtex year删除了对dc:date模板的调用,只是为了将代码全部保存在一个模板中

<xsl:template match="*" mode="bibtex-label">
  <xsl:variable name="surname" select="substring-after(rec:editor[1]/contact:fullName, ' ')"/>
  <xsl:variable name="safeSurname" select="translate($surname, $nameIn, $nameOut)" />
  <xsl:variable name="date"  select="substring-before(dc:date/text(), '-')"/>
  <xsl:value-of select="concat($safeSurname, ':', $date)" />
  <xsl:number value="count(preceding-sibling::rec:REC[substring-before(dc:date/text(), '-') = $date][translate(substring-after(rec:editor[1]/contact:fullName, ' '), $nameIn, $nameOut) = $safeSurname]) + 1" format="a"/>
</xsl:template>

首先,为了简化safe姓氏函数的
translate
函数,可以在XSLT顶部定义两个变量,如下所示

<xsl:variable name="nameIn" 
   select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.- 0123456789ñÑçÇáéíóúÃÉÃÓÚäëïöüÄËÃÖÜ'" />
<xsl:variable name="nameOut" 
   select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

这将允许您编写可读性更强的代码来获取格式化的姓氏

<xsl:variable name="safeSurname" select="translate($surname, $nameIn, $nameOut)" />

当您看到生成后缀的代码时,就会更加清楚,可以使用xsl:number函数来计算具有匹配年份和姓氏的前兄弟姐妹的数量。请注意使用format属性输出字母而不是数字:

<xsl:number 
   value="count(preceding-sibling::rec:REC
      [substring-before(dc:date/text(), '-') = $date]
      [translate(substring-after(rec:editor[1]/contact:fullName, ' '), $nameIn, $nameOut) = $safeSurname]
   ) + 1" 
   format="a"/>

在此代码中,$date是当前REC元素的年份

这是bibtex标签的完整匹配模板。注意:我已使用模式bibtex year删除了对dc:date模板的调用,只是为了将代码全部保存在一个模板中

<xsl:template match="*" mode="bibtex-label">
  <xsl:variable name="surname" select="substring-after(rec:editor[1]/contact:fullName, ' ')"/>
  <xsl:variable name="safeSurname" select="translate($surname, $nameIn, $nameOut)" />
  <xsl:variable name="date"  select="substring-before(dc:date/text(), '-')"/>
  <xsl:value-of select="concat($safeSurname, ':', $date)" />
  <xsl:number value="count(preceding-sibling::rec:REC[substring-before(dc:date/text(), '-') = $date][translate(substring-after(rec:editor[1]/contact:fullName, ' '), $nameIn, $nameOut) = $safeSurname]) + 1" format="a"/>
</xsl:template>


请提供示例源XML文档(小)和所需的确切结果。已更新!希望这会有帮助。您的输入文档很大而且是外部的。这不适合这样做。请提供一个简化的小示例输入文档,不要链接到场外。也请对预期输出执行相同操作。请删除与问题核心无关的所有细节。另外,不要使用省略号并指定XSLT版本。我已经更新了输入/输出。版本是1.0,但我并不特别介意更新版本的解决方案。请提供示例源XML文档(小)和确切的所需结果。已更新!希望这会有帮助。您的输入文档很大而且是外部的。这不适合这样做。请提供一个简化的小示例输入文档,不要链接到场外。也请对预期输出执行相同操作。请删除与问题核心无关的所有细节。另外,不要使用省略号并指定XSLT版本。我已经更新了输入/输出。版本是1.0,但我并不特别介意更新版本的解决方案。非常感谢!它工作得很好,虽然我认为它的某个地方有一个bug。我得到了一些末尾带有“b”的标签,但是搜索“a”等价物并没有找到任何结果。啊,我认为这是因为输入文档中有一些与之匹配的非选定结构。我想是的。这是一个用rec:rec元素名上的特定计数替换通用“*”元素计数的例子。我已经更正了XSLT,希望能解决它。非常感谢!它工作得很好,虽然我认为它的某个地方有一个bug。我得到了一些末尾带有“b”的标签,但是搜索“a”等价物并没有找到任何结果。啊,我认为这是因为输入文档中有一些与之匹配的非选定结构。我想是的。这是一个用rec:rec元素名上的特定计数替换通用“*”元素计数的例子。我已经更正了XSLT,希望这能解决它。