我有以下xml
<xml>
<para>
<number>1</number>
<text> Paragraph 1(<italic>A</italic>) is this para.</text>
</para>
</xml>
我想匹配文本元素,如果我发现一个模式以字段Paragraph开头,后跟空格后跟一个或多个数字后跟“(”后跟节点斜体和数字和关闭“)”。然后它应该在它周围放置一个锚标记。所以上面xml的输出应该是
<xml>
<para>
<number>1</number>
<text> <a href="Paragraph1(A)">Paragraph 1(<italic>A</italic>)</a> is this para.</text>
</para>
</xml>
即用标记替换Paragraph 1(<italic>A</italic>)
,href值应该是匹配的文本,没有任何空格和斜体节点。
任何帮助或提示如何处理正则表达式...
答案 0 :(得分:1)
这可以让您了解如何解决它:
<?xml version="1.0"?>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- Only our text element requires special handling here....-->
<xsl:template match="text">
<xsl:copy>
<xsl:choose>
<xsl:when test="matches(.,'Paragraph\s+\d*')">
<!-- Save original text value here -->
<xsl:variable name="temp" select="."/>
<!-- Save the value of <italic>x</italic> child element -->
<xsl:variable name="italic_val" select="italic/text()"/>
<xsl:analyze-string select="." regex="(Paragraph\s+\d*)">
<xsl:matching-substring>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="concat(replace(regex-group(1),'\s',''),'(',$italic_val,')')"/>
</xsl:attribute>
<xsl:value-of select="$temp"/>
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>DOESNT MATCH</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
它基本上使用XSLT标识模板来复制原始文档,并定义一个模板来处理<text>
元素。在那里它分析了它的Text()内容和适当的Regex:Paragraph。如果它发现它生成锚子结构。为此,我使用了一些临时变量。
这是我的输出文件:
<xml>
<para>
<number>1</number>
<text><a href="Paragraph1(A)"> Paragraph 1(A) is this para.</a></text>
</para>
</xml>
我仍然错过了第1段(<italic>A</italic>
),而不是我得到的内容:第1段(A)段,但这只是一些调整......
看看this link它可能有助于您了解XSLT中的正则表达式
注意它使用XSLT 2.0
答案 1 :(得分:1)
此XSLT 2.0样式表产生了所需的结果:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Only our text element requires special handling here....-->
<xsl:template match="text[matches(.,'Paragraph\s+\d*')]">
<xsl:copy>
<xsl:variable name="textElement" select="."/>
<xsl:analyze-string select="." regex="(Paragraph\s+\d*)(\(.*\))">
<xsl:matching-substring>
<a href="{concat(replace(regex-group(1),'\s',''),regex-group(2))}">
<xsl:apply-templates select="$textElement/node()"/>
</a>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
此正则表达式没有周围的引号:
".*(Paragraph ([0-9]+)`\`(<italic>([0-9])</italic>`\`)"
将为您提供一个外部级别捕获组,其中包含2个嵌入式捕获组,可为您提供值。 out级别捕获组是#1,2个嵌入式组#2和#3。
请注意,字面值'('使用'\
'进行转义,因为'('是正则表达式中的保留字符。
答案 3 :(得分:0)
为什么你需要正则表达式呢?下面的代码出了什么问题?
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/xml/para/text">
<xsl:copy>
<a href="Paragraph1(A)">
<xsl:apply-templates select="@*|node()"/>
</a>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>