XSLT 3.0获取紧邻前置元素属性值的问题排查
解决XSLT遍历脚注节点并获取前置元素属性的问题
首先,你遇到的「无法将字符串"a"转换为双精度数」错误,根源是代码里的./current() - 1完全用错了逻辑——current()返回的是当前正在处理的节点(比如<appnote>a</appnote>),你试图把节点的字符串内容做减法运算,自然会触发类型转换错误。另外,preceding::node()会选中当前节点之前的所有节点(包括其他父元素下的节点),这也不符合你要的「紧邻前置元素」需求。
下面是修正后的XSLT 3.0代码,可以完美实现你预期的效果:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0"> <xsl:mode on-no-match="shallow-copy"/> <xsl:template match="deposition"> <deposition> <xsl:apply-templates/> <!-- 生成独立的footnotes块 --> <footnotes> <xsl:for-each select="text//footnote"> <footitem> <xsl:value-of select="concat(., '=', preceding-sibling::node()[1][self::element()]/@n)"/> </footitem> </xsl:for-each> </footnotes> <!-- 生成独立的appnotes块 --> <appnotes> <xsl:for-each select="text//appnote"> <appitem> <xsl:value-of select="concat(., '=', preceding-sibling::node()[1][self::element()]/@n)"/> </appitem> </xsl:for-each> </appnotes> </deposition> </xsl:template> </xsl:stylesheet>
关键修改说明:
- 修复节点定位逻辑:用
preceding-sibling::node()[1]直接获取当前节点的紧邻前一个兄弟节点,这才是你需要的「前置元素」。加上[self::element()]是为了确保选中的是元素节点(排除空白文本节点等非元素节点)。 - 拆分独立注释块:按照你的预期,把脚注和应用注释分别放在
<footnotes>和<appnotes>两个独立的块中,而非混在同一个块里。 - 正确拼接内容:使用
concat()函数替代||(虽然XSLT 3.0支持||,但concat()兼容性更好),把脚注标识和前置元素的@n属性值拼接成你要的格式。 - 简化模板结构:去掉了冗余的根模板,因为
<xsl:mode on-no-match="shallow-copy"/>已经会默认处理根节点及其他未匹配的节点。
用这个代码处理你的XML,第一个<deposition>会生成你预期的结构:
<footnotes> <footitem>1=def</footitem> <footitem>2=ghi</footitem> <footitem>3=jkl</footitem> <footitem>4=seg1</footitem> </footnotes> <appnotes> <appitem>a=abc</appitem> </appnotes>
内容的提问来源于stack exchange,提问作者jbrehr
相关产品推荐
相关产品推荐

