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

时间:2017-08-24 23:18:15

标签: regex xml xslt xslt-2.0

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

这是我的XML

replace()

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

<?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>

这将是所需输出的一部分

<?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[]的谓词中ancestor::document/researchNote[$1]。该用途给出了错误。那么,是否可以在replace()函数中以类似的方式执行我想要的操作。

谢谢,迈克尔

1 个答案:

答案 0 :(得分:1)

正如我在评论中所说,处理此问题的适当工具是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