来自 replace() 的匹配正则表达式字符串可以在 concat() 内部的替换中使用吗?XSLT 2 或 3



我有一个示例 xml 文件,其中<document>节点包含一个<docText>和零、一个或两个<researchNote>的子节点。当出现文本字符串 [fn:1] 时,我想将其替换为包含<researchNote>的第一个实例的<span>,如果 [fn:2] 我想替换为<researchNote>的第二个实例。当我不包含谓词或静态包含谓词作为 [1] 或 [2] 时,我使用replace()让它用于第一个实例。当我尝试使用正则表达式中的 $1 使用匹配的字符串时,来自replace()匹配的整数,我收到错误。我想在下面的XML和XSLT中找到一种方法来引用整数。

这是我的 XML

<?xml version="1.0" encoding="UTF-8"?>
<project>
<document id="doc1">
<docText>This is a test of an inline footnote reference[fn:1]. This is a second[fn:2] footnote.</docText>
<researchNote>First footnote.</researchNote>
<researchNote>Second footnote.</researchNote>
</document>
<document id="doc2">
<docText>This is a test of an inline footnote reference[fn:1].</docText>
<researchNote>First footnote.</researchNote>
</document>
</project>

这是我的 XSL 文件。我可以使用 XSLT 3.0 或 2.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="xsl">
<xsl:output method="html" html-version="5.0" encoding="utf-8"  indent="yes"/>
<xsl:template match="/">
<html>
<head><title>Test</title></head>
<body><xsl:apply-templates select="project/document/docText"/></body>
</html>
</xsl:template>
<xsl:template match="docText">
<p>
<xsl:variable name="string1" select="replace(.,'[fn:(d)]', concat('&lt;span class=&quot;fn&quot; id=&quot;',concat(ancestor::document/@id,'-fn'),'&quot;&gt; (',ancestor::document/researchNote[1],')&lt;/span&gt;'))"/>
<xsl:value-of select="$string1" disable-output-escaping="yes" />
</p>
</xsl:template>
</xsl:stylesheet>

这将是所需输出的一部分

<p>This is a test of an inline footnote reference<span class="fn" id="doc1-fn"> (First footnote.)</span>. This is a second<span class="fn" id="doc1-fn"> (Second footnote.)</span> footnote.</p>

我想使用[fn:(d)]匹配的数字,例如。$1,在这种情况下将是 1 或 2,在像这样ancestor::document/researchNote[$1]的谓词中ancestor::document/researchNote[]。这种用法会产生错误。那么,是否可以在 replace(( 函数中或以类似的方式做我想做的事情。

谢谢,迈克尔

正如我在评论中所说,处理此问题的适当工具是xsl:analyze-string指令,而不是只能输出字符串结果的replace()函数。

尝试:

<xsl:template match="docText">
<xsl:variable name="doc" select="ancestor::document" />
<p>
<xsl:analyze-string select="." regex="[fn:(d+)]" >
<xsl:matching-substring>
<span class="fn" id="{$doc/@id}-fn">
<xsl:text>(</xsl:text>
<xsl:value-of select="$doc/researchNote[number(regex-group(1))]" />
<xsl:text>)</xsl:text>
</span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="." />
</xsl:non-matching-substring>
</xsl:analyze-string>
</p>
</xsl:template>

工作演示:http://xsltransform.net/6pS1zDp/5

最新更新