带符号的 XSLT 2.0 正则表达式

XSLT 2.0 Regex with Ampersands

我正在尝试将文本文件转换为有效的 HTML。我想将 &lt;&lt; 更改为 <dfn> 元素,将 &gt;&gt; 更改为结束 </dfn> 元素。

示例源文档:

  <!DOCTYPE html>
  <html>
     <head>
        <title></title>
     </head>
     <body>
           <p>The term &lt;&lt;absorb&gt;&gt;means foo. 
              The term &lt;&lt;evaporate&gt;&gt; 
              means to foo.</p>
     </body>
  </html>

到目前为止不成功的代码:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output
        method="xhtml"
        html-version="5.0"
        omit-xml-declaration="yes"
        encoding="utf-8"
        indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*/text()">        
        <xsl:analyze-string select="." regex="(&lt;&lt;)(\.?)(&gt;&gt;)" flags="sx">
            <xsl:matching-substring>
                <dfn>
                    <xsl:value-of select="regex-group(2)"/>
                </dfn>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:copy-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>        
    </xsl:template>

</xsl:stylesheet>

各种版本的正则表达式都抓住了左侧 &lt;&lt;,但我永远无法匹配到比这更远的地方。我被难住了。

对于 regex="(&lt;&lt;)(\.?)(&gt;&gt;)"\. 匹配文字点字符,而您想匹配 >> 之前的任何字符序列,不是吗?所以你想要 regex="(&lt;&lt;)(.*?)(&gt;&gt;)"" 来捕获字符。有关示例,请参阅 http://xsltransform.net/eiZQaFi/1

只需调整您的正则表达式以定位您要包装在标签中的字符串:

<xsl:template match="*/text()">        
    <xsl:analyze-string select="." regex="&lt;&lt;(.+?)&gt;&gt;" flags="sx">
        <xsl:matching-substring>
            <dfn>
                <xsl:value-of select="regex-group(1)"/>
            </dfn>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
            <xsl:copy-of select="."/>
        </xsl:non-matching-substring>
    </xsl:analyze-string>        
</xsl:template>