XSLT 搜索和替换标点符号
XSLT search and replace punctuation mark
我有一个 XSLT 级联传输 XML 到 TeX。在最后一步中,我有一个简单的 xml 文件,其中包含两个标签之间的所有文本,我想应用多个搜索和替换例程。
所以这样的输入文件:
<start>
.–
,–
{–
</start>
与此 XSLT 一起应用时(或多或少逐字取自 Replacing strings in various XML files)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="list">
<words>
<word>
<search> / </search>
<replace>\allowbreak\,\slash\,\allowbreak{}</replace>
</word>
<word>
<search>.–</search>
<replace>{\dotdash}</replace>
</word>
<word>
<search>,–</search>
<replace>{\commadash}</replace>
</word>
<word>
<search>;–</search>
<replace>{\semicolondash}</replace>
</word>
<word>
<search>!–</search>
<replace>{\excdash}</replace>
</word>
</words>
</xsl:param>
<xsl:template match="@*|*|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="search" select="concat('(',string-join($list/words/word/search,'|'),')')"/>
<xsl:analyze-string select="." regex="{$search}">
<xsl:matching-substring>
<xsl:value-of select="$list/words/word[search=current()]/replace"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
应该有以下输出:
\dotdash{}
\commadash{}
{–
不幸的是,“{–”似乎触发了什么并消失了。谁能解释一下为什么?
很高兴您链接到的原始答案有所帮助。如果您还没有,请考虑投票。 ;-)
问题是 .
在正则表达式中很特殊。所以 <search>.–</search>
将匹配任何后跟 -
.
的字符
您应该在搜索变量中转义 .
:
<xsl:variable name="search" select="replace(concat('(',string-join($list/words/word/search,'|'),')'),'\.','\.')"/>
您还需要转义任何其他特殊的正则表达式字符,因此您可以考虑创建一个 xsl:function
以简化该部分。
这是一个函数示例,对于初学者来说,它会转义 .
和 {
...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="Whosebug example" exclude-result-prefixes="so">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="list">
<words>
<word>
<search> / </search>
<replace>\allowbreak\,\slash\,\allowbreak{}</replace>
</word>
<word>
<search>.–</search>
<replace>{\dotdash}</replace>
</word>
<word>
<search>,–</search>
<replace>{\commadash}</replace>
</word>
<word>
<search>;–</search>
<replace>{\semicolondash}</replace>
</word>
<word>
<search>!–</search>
<replace>{\excdash}</replace>
</word>
<!--<word>
<search>{–</search>
<replace>bam!</replace>
</word>-->
</words>
</xsl:param>
<xsl:function name="so:escapeRegex">
<xsl:param name="regex"/>
<xsl:analyze-string select="$regex" regex="\.|\{{">
<xsl:matching-substring>
<xsl:value-of select="concat('\',.)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="@*|*|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="search" select="so:escapeRegex(concat('(',string-join($list/words/word/search,'|'),')'))"/>
<xsl:analyze-string select="." regex="{$search}">
<xsl:matching-substring>
<xsl:message>"<xsl:value-of select="."/>" matched <xsl:value-of select="$search"/></xsl:message>
<xsl:value-of select="$list/words/word[search=current()]/replace"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
如果您取消注释 list
参数中的最后一个 word
,它将替换示例中的 {–
。
我有一个 XSLT 级联传输 XML 到 TeX。在最后一步中,我有一个简单的 xml 文件,其中包含两个标签之间的所有文本,我想应用多个搜索和替换例程。
所以这样的输入文件:
<start>
.–
,–
{–
</start>
与此 XSLT 一起应用时(或多或少逐字取自 Replacing strings in various XML files)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="list">
<words>
<word>
<search> / </search>
<replace>\allowbreak\,\slash\,\allowbreak{}</replace>
</word>
<word>
<search>.–</search>
<replace>{\dotdash}</replace>
</word>
<word>
<search>,–</search>
<replace>{\commadash}</replace>
</word>
<word>
<search>;–</search>
<replace>{\semicolondash}</replace>
</word>
<word>
<search>!–</search>
<replace>{\excdash}</replace>
</word>
</words>
</xsl:param>
<xsl:template match="@*|*|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="search" select="concat('(',string-join($list/words/word/search,'|'),')')"/>
<xsl:analyze-string select="." regex="{$search}">
<xsl:matching-substring>
<xsl:value-of select="$list/words/word[search=current()]/replace"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
应该有以下输出:
\dotdash{}
\commadash{}
{–
不幸的是,“{–”似乎触发了什么并消失了。谁能解释一下为什么?
很高兴您链接到的原始答案有所帮助。如果您还没有,请考虑投票。 ;-)
问题是 .
在正则表达式中很特殊。所以 <search>.–</search>
将匹配任何后跟 -
.
您应该在搜索变量中转义 .
:
<xsl:variable name="search" select="replace(concat('(',string-join($list/words/word/search,'|'),')'),'\.','\.')"/>
您还需要转义任何其他特殊的正则表达式字符,因此您可以考虑创建一个 xsl:function
以简化该部分。
这是一个函数示例,对于初学者来说,它会转义 .
和 {
...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="Whosebug example" exclude-result-prefixes="so">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="list">
<words>
<word>
<search> / </search>
<replace>\allowbreak\,\slash\,\allowbreak{}</replace>
</word>
<word>
<search>.–</search>
<replace>{\dotdash}</replace>
</word>
<word>
<search>,–</search>
<replace>{\commadash}</replace>
</word>
<word>
<search>;–</search>
<replace>{\semicolondash}</replace>
</word>
<word>
<search>!–</search>
<replace>{\excdash}</replace>
</word>
<!--<word>
<search>{–</search>
<replace>bam!</replace>
</word>-->
</words>
</xsl:param>
<xsl:function name="so:escapeRegex">
<xsl:param name="regex"/>
<xsl:analyze-string select="$regex" regex="\.|\{{">
<xsl:matching-substring>
<xsl:value-of select="concat('\',.)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="@*|*|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="search" select="so:escapeRegex(concat('(',string-join($list/words/word/search,'|'),')'))"/>
<xsl:analyze-string select="." regex="{$search}">
<xsl:matching-substring>
<xsl:message>"<xsl:value-of select="."/>" matched <xsl:value-of select="$search"/></xsl:message>
<xsl:value-of select="$list/words/word[search=current()]/replace"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
如果您取消注释 list
参数中的最后一个 word
,它将替换示例中的 {–
。