Sve*_*vei 10 regex xslt markdown
我正在将我的XSLT样式表转换为文档,我想在每个代码块的注释节点中获得丰富的经验,因此我想将以下注释和输出转换为xhtml:
串:
# This is a title with __bold__ text and *italic* # This is just a normal line - list point with some __bold__ - list point with a "link"[http://www.stackoverflow.com]
通缉输出:
<h1> This is a title with <strong>bold</strong> and <span>italic</span> </h1>
<p>This is a normal line</p>
<ul>
<li>list point with some <strong>bold</strong></li>
<li>list point with a <a href="http://www.stackoverflow.com">link</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)
我试过一个递归函数,它从规则集递归地使用xsl:analyze-string,但是找不到一个非常好用的解决方案.
任何人最近都做过这个,或者是否有一些框架可以执行此操作?
提前谢谢!:)
编辑:添加了一个脏例子:
<!-- Output comments -->
<xsl:template match="comment()" mode="COMMENT">
<xsl:copy-of select="ips:groupReplace(normalize-space(.),
'
(.*)(\n|\r)(.*),
(.*)\*(.*)\*(.*),
(.*)\*\*(.*)\*\*(.*),
(.*)__(.*)__(.*),
(.*)#(.*)#(.*),
(.*)-(.*)
',
'
br,
span.italic,
span.bold,
strong,
h1,
li
')" />
</xsl:template>
<!-- Initializing the iterateRegex function -->
<xsl:function name="ips:groupReplace">
<xsl:param name="string" as="xs:string" />
<xsl:param name="search" />
<xsl:param name="replace" />
<xsl:variable name="regex" select="tokenize($search, ',')" />
<xsl:variable name="replacements" select="tokenize($replace, ',')" />
<xsl:copy-of select="ips:iterateRegex(count($replacements), $string, $regex, $replacements)" />
</xsl:function>
<!-- Iterate each regex -->
<xsl:function name="ips:iterateRegex">
<xsl:param name="counter" />
<xsl:param name="string" />
<xsl:param name="list_regex" />
<xsl:param name="list_replace" />
<xsl:variable name="newStr">
<xsl:analyze-string select="$string" regex="{normalize-space($list_regex[$counter])}" flags="xm">
<xsl:matching-substring>
<xsl:variable name="cc" select="contains($list_replace[$counter], '.')" />
<xsl:variable name="tag" select="normalize-space(if ($cc) then (substring-before($list_replace[$counter], '.')) else ($list_replace[$counter]))" />
<xsl:copy-of select="regex-group(1)" />
<xsl:choose>
<xsl:when test="normalize-space(regex-group(2)) = ''">
<xsl:element name="{$tag}" />
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$tag}" >
<xsl:if test="$cc">
<xsl:attribute name="class" select="substring-after($list_replace[$counter],'.')" />
</xsl:if>
<xsl:copy-of select="regex-group(2)" />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:copy-of select="regex-group(3)" />
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:copy-of select="." />
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:variable name="count" select="number($counter) - 1" />
<xsl:choose>
<xsl:when test="$count > 0">
<xsl:copy-of select="ips:iterateRegex($count, $newStr, $list_regex, $list_replace)" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$newStr" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
Run Code Online (Sandbox Code Playgroud)
小智 14
我想你需要一个解析器.所以这个样式表实现了一个冗长的:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="text" name="block">
<xsl:param name="pString" select="."/>
<xsl:if test="$pString != ''">
<xsl:choose>
<xsl:when test="starts-with($pString,'#')">
<xsl:call-template name="header">
<xsl:with-param name="pString"
select="substring($pString,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($pString,'
')">
<xsl:call-template name="list">
<xsl:with-param name="pString"
select="substring($pString,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="paragraph">
<xsl:with-param name="pString"
select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="header">
<xsl:param name="pString"/>
<xsl:variable name="vInside"
select="substring-before($pString,'#
')"/>
<xsl:choose>
<xsl:when test="$vInside != ''">
<h1>
<xsl:call-template name="inline">
<xsl:with-param name="pString" select="$vInside"/>
</xsl:call-template>
</h1>
<xsl:call-template name="block">
<xsl:with-param name="pString"
select="substring-after($pString,'#
')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="paragraph">
<xsl:with-param name="pString"
select="concat('#',$pString)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="list">
<xsl:param name="pString"/>
<xsl:variable name="vCheckList" select="starts-with($pString,'- ')"/>
<xsl:choose>
<xsl:when test="$vCheckList">
<ul>
<xsl:call-template name="listItem">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</ul>
<xsl:call-template name="block">
<xsl:with-param name="pString">
<xsl:call-template name="afterlist">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="block">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="paragraph">
<xsl:param name="pString"/>
<xsl:choose>
<xsl:when test="contains($pString,'
')">
<p>
<xsl:value-of select="substring-before($pString,'
')"/>
</p>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:value-of select="$pString"/>
</p>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="block">
<xsl:with-param name="pString"
select="substring-after($pString,'
')"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="afterlist">
<xsl:param name="pString"/>
<xsl:choose>
<xsl:when test="starts-with($pString,'- ')">
<xsl:call-template name="afterlist">
<xsl:with-param name="pString"
select="substring-after($pString,'
')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pString"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="listItem">
<xsl:param name="pString"/>
<xsl:if test="starts-with($pString,'- ')">
<li>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="substring-before(substring($pString,3),'
')"/>
</xsl:call-template>
</li>
<xsl:call-template name="listItem">
<xsl:with-param name="pString"
select="substring-after($pString,'
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="inline">
<xsl:param name="pString" select="."/>
<xsl:if test="$pString != ''">
<xsl:choose>
<xsl:when test="starts-with($pString,'__')">
<xsl:call-template name="strong">
<xsl:with-param name="pString"
select="substring($pString,3)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($pString,'*')">
<xsl:call-template name="span">
<xsl:with-param name="pString"
select="substring($pString,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($pString,'"')">
<xsl:call-template name="link">
<xsl:with-param name="pString"
select="substring($pString,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($pString,1,1)"/>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="substring($pString,2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="strong">
<xsl:param name="pString"/>
<xsl:variable name="vInside" select="substring-before($pString,'__')"/>
<xsl:choose>
<xsl:when test="$vInside != ''">
<strong>
<xsl:value-of select="$vInside"/>
</strong>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="substring-after($pString,'__')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'__'"/>
<xsl:call-template name="inline">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="span">
<xsl:param name="pString"/>
<xsl:variable name="vInside" select="substring-before($pString,'*')"/>
<xsl:choose>
<xsl:when test="$vInside != ''">
<span>
<xsl:value-of select="$vInside"/>
</span>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="substring-after($pString,'*')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'*'"/>
<xsl:call-template name="inline">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="link">
<xsl:param name="pString"/>
<xsl:variable name="vInside"
select="substring-before($pString,'"')"/>
<xsl:choose>
<xsl:when test="$vInside != ''">
<xsl:call-template name="href">
<xsl:with-param name="pString"
select="substring-after($pString,'"')"/>
<xsl:with-param name="pInside" select="$vInside"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'"'"/>
<xsl:call-template name="inline">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="href">
<xsl:param name="pString"/>
<xsl:param name="pInside"/>
<xsl:variable name="vHref"
select="substring-before(substring($pString,2),']')"/>
<xsl:choose>
<xsl:when test="starts-with($pString,'[') and $vHref != ''">
<a href="{$vHref}">
<xsl:value-of select="$pInside"/>
</a>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="substring-after($pString,']')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('"',$pInside,'"')"/>
<xsl:call-template name="inline">
<xsl:with-param name="pString" select="$pString"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
有了这个输入:
<text>
# This is a title with __bold__ text and *italic* #
This is just a normal line
- list point with some __bold__
- list point with a "link"[http://www.stackoverflow.com]
</text>
Run Code Online (Sandbox Code Playgroud)
输出:
<h1> This is a title with
<strong>bold</strong> text and
<span>italic</span>
</h1>
<p>This is just a normal line</p>
<ul>
<li>list point with some
<strong>bold</strong>
</li>
<li>list point with a
<a href="http://www.stackoverflow.com">link</a>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
注意:查看有多少模板相似(它们遵循模式),因此可以对这些模板进行参数化.在这种情况下我没有这样做,因为似乎有更多问题需要某种解析器,所以到本周末我将重新发布一个实现功能解析器和解析器组合模式的答案,这使得编写解析器变得非常容易(只写它的语法规则).
编辑:XSLT 2.0解决方案.这个样式表:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="text">
<xsl:param name="pString" select="."/>
<xsl:analyze-string select="$pString"
regex="(#(.*)#
)|((- (.*)
)+)">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<h1>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="regex-group(2)"/>
</xsl:call-template>
</h1>
</xsl:when>
<xsl:when test="regex-group(3)">
<ul>
<xsl:call-template name="list">
<xsl:with-param name="pString"
select="regex-group(3)"/>
</xsl:call-template>
</ul>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:if test=".!='
'">
<p>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="normalize-space(.)"/>
</xsl:call-template>
</p>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="list">
<xsl:param name="pString"/>
<xsl:analyze-string select="$pString" regex="- (.*)
">
<xsl:matching-substring>
<li>
<xsl:call-template name="inline">
<xsl:with-param name="pString"
select="regex-group(1)"/>
</xsl:call-template>
</li>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="inline">
<xsl:param name="pString" select="."/>
<xsl:analyze-string select="$pString"
regex="(__(.*)__)|(\*(.*)\*)|("(.*)"\[(.*)\])">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<strong>
<xsl:value-of select="regex-group(2)"/>
</strong>
</xsl:when>
<xsl:when test="regex-group(3)">
<span>
<xsl:value-of select="regex-group(4)"/>
</span>
</xsl:when>
<xsl:when test="regex-group(5)">
<a href="{regex-group(7)}">
<xsl:value-of select="regex-group(6)"/>
</a>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
输出:
<h1> This is a title with
<strong>bold</strong> text and
<span>italic</span>
</h1>
<p>This is just a normal line</p>
<ul>
<li>list point with some
<strong>bold</strong>
</li>
<li>list point with a
<a href="http://www.stackoverflow.com">link</a>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
Dim*_*hev 10
这种转变(111行):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my"
exclude-result-prefixes="xml xsl xs my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vLines" select="tokenize(., '\n')"/>
<xsl:sequence select="my:parse-lines($vLines)"/>
</xsl:template>
<xsl:function name="my:parse-lines" as="element()*">
<xsl:param name="pLines" as="xs:string*"/>
<xsl:sequence select=
"my:parse-line($pLines, 1, count($pLines))"/>
</xsl:function>
<xsl:function name="my:parse-line" as="element()*">
<xsl:param name="pLines" as="xs:string*"/>
<xsl:param name="pLineNum" as="xs:integer"/>
<xsl:param name="pTotalLines" as="xs:integer"/>
<xsl:if test="not($pLineNum gt $pTotalLines)">
<xsl:variable name="vLine" select="$pLines[$pLineNum]"/>
<xsl:variable name="vLineLength"
select="string-length($vLine)"/>
<xsl:choose>
<xsl:when test=
"starts-with($vLine, '#')
and
ends-with($vLine, '#')
">
<xsl:variable name="vInnerString"
select="substring($vLine, 2, $vLineLength -2)"/>
<h1>
<xsl:sequence select="my:parse-string($vInnerString)"/>
</h1>
<xsl:sequence select=
"my:parse-line($pLines, $pLineNum+1, $pTotalLines)"/>
</xsl:when>
<xsl:when test=
"starts-with($vLine, '- ')
and
not(starts-with($pLines[$pLineNum -1], '- '))
">
<ul>
<li>
<xsl:sequence select="my:parse-string(substring($vLine, 2))"/>
</li>
<xsl:sequence select=
"my:parse-line($pLines, $pLineNum+1, $pTotalLines)"/>
</ul>
</xsl:when>
<xsl:when test="starts-with($vLine, '- ')">
<li>
<xsl:sequence select="my:parse-string(substring($vLine, 2))"/>
</li>
<xsl:sequence select=
"my:parse-line($pLines, $pLineNum+1, $pTotalLines)"/>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:sequence select="my:parse-string($vLine)"/>
</p>
<xsl:sequence select=
"my:parse-line($pLines, $pLineNum+1, $pTotalLines)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:function>
<xsl:function name="my:parse-string" as="node()*">
<xsl:param name="pS" as="xs:string"/>
<xsl:analyze-string select="$pS" flags="x" regex=
'(__(.*?)__)
|
(\*(.*?)\*)
|
("(.*?)"\[(.*?)\])
'>
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<strong>
<xsl:sequence select="my:parse-string(regex-group(2))"/>
</strong>
</xsl:when>
<xsl:when test="regex-group(3)">
<span>
<xsl:sequence select="my:parse-string(regex-group(4))"/>
</span>
</xsl:when>
<xsl:when test="regex-group(5)">
<a href="{regex-group(7)}">
<xsl:sequence select="regex-group(6)"/>
</a>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于此XML文档时(提供的文本与嵌套构造复杂并包含在元素中):
<t># This is a title with __bold__ text and *italic* #
This is just a normal line
- list point with some __bold__
- list point with a __*"link"[http://www.stackoverflow.com]*__</t>
Run Code Online (Sandbox Code Playgroud)
产生想要的正确输出:
<h1> This is a title with <strong>bold</strong> text and <span>italic</span>
</h1>
<p>This is just a normal line</p>
<p/>
<ul>
<li> list point with some <strong>bold</strong>
</li>
<li> list point with a <strong>
<span>
<a href="http://www.stackoverflow.com">link</a>
</span>
</strong>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
请注意:XPath 2.0和XSLT 2.0的RegEx机制足以解决此问题.