参考以下MS提供的指南: MS 参考书目样式编辑指南 和 IEEE 参考样式 IEEE xsl 样式文件。 我正在为 word 365 自定义 IEEE 参考书目样式文件,并且希望在用户未填写重要字段时向用户显示一条消息。对于书籍类型,需要填写以下字段。以下对书籍部分的代码片段更改可显示所需的书籍字段:
<!-- Variable containing all necessary data for a certain style of bibliography. -->
<xsl:variable name="data">
<general>
<stylename>IEEE - Reference Order</stylename>
<version>2009.05.23</version>
<description>An implementation of the IEEE style.</description>
<URL></URL>
<author>Yves Dhondt ([email protected])</author>
<comments></comments>
<display_errors>yes</display_errors>
<citation_as_link>yes</citation_as_link>
</general>
<importantfields>
<source type="Book">
<b:ImportantField>b:Title</b:ImportantField>
<b:ImportantField>b:StandardNumber</b:ImportantField>
<b:ImportantField>b:Edition</b:ImportantField>
<b:ImportantField>b:URL</b:ImportantField>
</source>
</xsl:variable>
但是当用户忘记输入重要字段时,我所做的更改会显示错误,导致参考书目为空:
<!-- Check if required book fields are populated -->
<xsl:template match="b:Source[b:SourceType = 'Book']">
<xsl:variable name="Edition">
<xsl:when test="string-length($Edition)=0">
<xsl:text>Enter Revision</xsl:text>
<xsl:value-of select="$Edition" />
</xsl:when>
</xsl:variable>
</xsl:template>
我的 xsl 是错误的,可能是因为我是 xsl 新手,或者我没有在整个 xsl 文件中获得正确的位置,或者两者兼而有之!
[注意,我在这方面做了更多的工作,但它仍然只是一个垫脚石 - 请参阅答案底部的关键代码的新版本]
这可能会让您入门(我对 XSLT 也不太熟悉),但是由于现有 XSL 代码中使用的通用方法,找到一个合适的地方进行必要的修改是很棘手的。下面有一些注意事项。
寻找以下模板
<xsl:template name="format-bibliography-table-column">
在下面,查找此代码:
<!-- Else go for the source type element if available. -->
<xsl:when test="string-length(msxsl:node-set($data)/bibliography/source[@type = $sourcetype]/column[@id = $columnId]/format) > 0 ">
<xsl:value-of select="msxsl:node-set($data)/bibliography/source[@type = $sourcetype]/column[@id = $columnId]/format"/>
</xsl:when>
并将其更改为
<xsl:when test="string-length(msxsl:node-set($data)/bibliography/source[@type = $sourcetype]/column[@id = $columnId]/format) > 0 ">
<xsl:if test = "msxsl:node-set($data)/general/display_errors = 'yes'">
<xsl:choose>
<xsl:when test="$sourcetype = 'Book'" >
<xsl:choose>
<xsl:when test="string-length($source/b:Edition) > 0" />
<xsl:otherwise>
<xsl:choose>
<!-- Put an asterisk before the source id ([1] etc.).
If you do more tests, you may prefer to modify the code so that only one asterisk is inserted.
Probably useful to put the Source's tag in the output too.
-->
<xsl:when test="$columnId = 1">
<xsl:text><b>*</b></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text><b>Edition is missing. </b></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:if>
并尝试一下。如果图书引文中的“版本”字段缺失或为空,则您应该在 ID 之前看到一个星号(“
[1]
”等,然后在参考书目中相关条目的开头处以粗体显示“Edition is missing.
”)接下来你生成它。
我在代码中选择了该特定位置,因为我认为该样式表默认使用
format-bibliography-table-column
模板而不是 format-bibliography-as-paragraphs
模板,并且 Word 本身在 b 中传递源类型(“Book”等): SourceType 元素,而不是(在大多数情况下)b:Type 元素。
(Yves Dhondt 的“BibWord”系统可以重新利用 b:Type 来保存源类型,因为这允许他引入其他源类型,但据我所知,当 Word 调用此功能时,该功能实际上并未使用样式表。)
如果您在合适的测试源中没有看到更改,您可能需要将此代码复制到检查源类型的其他 3 个位置,并进行一处更改。
其中之一位于 xsl:when test 紧接其上方,您可以在其中放置类似的代码,但您可以更改
<xsl:when test="$sourcetype = 'Book'" >
到
<xsl:when test="$type = 'Book'" >
另外两个地方位于 format-bibliography-as-paragraphs 模板中的等效部分(其中现有代码也略有不同)。
一些注意事项和警告:
您必须在需要能够重新生成此参考书目的每台计算机上安装样式表的副本。
之所以很难找到正确的位置来进行此更改,是因为 XSL 分两个阶段构建 HTML - 第一个阶段,它根据源类型以及输出的类型和位置选择需要使用的格式((段落、表的第 1 列或表的第 2 列)。“格式只是一种“模式” - 稍后,源中的实际值将插入到模式中,参见
printf()
函数用 C 语言调用,例如我编写的代码只是将文本插入名为“format”的变量中。
我只有时间让这一件事发挥作用 - 大概您想测试其他“重要项目”的存在。不知道如何扩展此代码来做到这一点,但通过 xsl:for-each 选取与特定源类型相关的一组重要项目可能是有意义的。
值得注意的是,尝试将代码插入到尝试“匹配”源类型的单独模板中的原因是,样式表有时被称为“填空”或“导航”样式表,其中,本质上,单个模板从它接收到的 XML 文档的顶部开始,挑选出它需要的内容,根据需要调用其他模板。您可以看到这一点,因为整个样式表中只有一个“匹配” - <xsl:template match="/">
。另外,正如其他人所指出的,填充变量“Edition”不会向 HTML 输出任何内容,除非您在单独的步骤中执行此操作。
<xsl:if test = "msxsl:node-set($data)/general/display_errors = 'yes'">
<xsl:variable name="missing">
<xsl:for-each select="msxsl:node-set($data)/importantfields/source[@type = $sourcetype]/b:ImportantField">
<xsl:variable name="importantfield" select="." />
<xsl:if test="string-length($source/*[name() = $importantfield]) = 0" >
<missingfield>
<xsl:value-of select="$importantfield"/>
</missingfield>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="$missing !=''">
<!-- soe hard coded assumptions about columns here. Should really add to the metadata in data/bibliography/columns and work with that-->
<xsl:choose>
<xsl:when test="$columnId = 1">
<xsl:text><b>*</b></xsl:text>
</xsl:when>
<xsl:when test="$columnId = 2">
<xsl:text><b>Fields missing from Source with ID "</xsl:text>
<xsl:value-of select="$source/b:Tag" />
<xsl:text>": </xsl:text>
<xsl:variable name="missingfieldcount" select="count(msxsl:node-set($missing)/missingfield)" />
<xsl:for-each select="msxsl:node-set($missing)/missingfield">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text>; </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>. </b></xsl:text>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:if>
注意: 对空/缺失作者、编辑等的检测是不正确的,因为在 importantfield 包含多步骤路径(例如
test="string-length($source/*[name() = $importantfield])
)的情况下
b:Author/b:Author/b:NameList
可能根本不起作用,并且对空性的测试可能不正确。我确信更熟悉 XSL 的人可以解决这些问题,但正确地进行检查可能需要更多的复杂性。由于我不是那个人,我可能会尝试通过沿着“重要字段”列表的方式引入一组新的“要测试的东西”来使自己变得更简单,但目的是使其更简单测试并更容易输出文本,而无需所有这些“b:”。