如何在MODS元数据XSLT转换中去除拼接列表的多余分隔符
我来帮你解决这个MODS元数据转换的问题!你遇到的核心问题是当前的join模板没有过滤空元素,而且position()是基于原始节点的位置,不是过滤后的非空节点。咱们一步步调整代码来解决:
第一步:过滤空元素,传递有效节点列表
先修改调用join模板的代码,把空的子元素直接排除在外,只传递包含非空白内容的节点:
<xsl:template match="mods:mods/mods:subject"> <tr> <td class="standardFieldName">Subject(s)</td> <td class="standardFieldValue"> <xsl:call-template name="join"> <!-- 只筛选有非空白内容的子元素,直接排除空的<titleInfo> --> <xsl:with-param name="valueList" select="*[normalize-space(.)]"/> <xsl:with-param name="separator" select="' -- '"/> </xsl:call-template> <xsl:text>

</xsl:text> </td> </tr> </xsl:template>
第二步:优化join模板逻辑,基于过滤后的节点处理位置
然后调整join模板的逻辑,确保只对过滤后的非空节点处理,避免开头出现多余分隔符:
<xsl:template name="join" > <xsl:param name="valueList" select="''"/> <xsl:param name="separator" select="','"/> <!-- 先检查是否有有效节点 --> <xsl:if test="$valueList"> <!-- 输出第一个有效节点,不加前置分隔符 --> <xsl:value-of select="$valueList[1]"/> <!-- 对剩余的每个节点,先加分隔符再输出内容 --> <xsl:for-each select="$valueList[position() > 1]"> <xsl:value-of select="concat($separator, .)"/> </xsl:for-each> </xsl:if> </xsl:template>
为什么这样改能解决问题?
- 过滤空元素:
*[normalize-space(.)]会自动排除像空<titleInfo>这类没有实际文本内容的节点,从根源上避免了空元素带来的多余--分隔符。 - 基于过滤后的节点处理位置:修改后的
join模板先输出第一个有效节点,再给后续的每个节点添加前置分隔符——不管第一个非空元素是<name>、<topic>还是<genre>,都不会出现开头的多余分隔符。
如果之后需要更精确的元素筛选(比如只保留特定类型的元素),可以调整过滤条件,比如*[self::mods:name or self::mods:topic or self::mods:genre][normalize-space(.)],但当前的逻辑已经能满足你描述的需求。
内容的提问来源于stack exchange,提问作者Leigh Ann Martin
相关产品推荐
相关产品推荐

