在字符串 xslt 的开头和结尾链接时删除括号
Removing Parenthesis when linked at beginning and end of string xslt
我正在使用 XSLT 从标签中删除括号,但仅当它们位于开头和结尾时,并且仅当链接时。
例如
(标签(1))变成标签(1)
但是
(标签) (1) 仍然是 (标签) (1)
具体编辑
更多示例:
(1) 变成 1
(这是)(一个(标签))仍然是(这是)(一个(标签))
(This (is) (a label)) 变成 This (is) (a label)
两者之间有任何变化
我认为我有一个解决方案,方法是依次测试字符并保留一个计数器来跟踪它们是否已链接,但我仍然遗漏了一些东西。感谢任何帮助。
这是我当前的代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes" method="xml" doctype-system="\ukfs11\Bks_RAPS\XML\DTDs\TFB\TFB.dtd"/>
<xsl:param name="labelstack"/>
<xsl:param name="labeltest"/>
<xsl:template match="//label[matches(.,'^\(.*\)$')]">
<xsl:param name="labelstack" select="substring(., 1, string-length(.) - 1)"/>
<xsl:param name="labelcounter"/>
<xsl:call-template name="loop1">
<xsl:with-param name="labelstack" select="$labelstack"/>
<xsl:with-param name="labelcounter" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="loop1">
<xsl:param name="labeltest" select="substring($labelstack, 1,1)"/>
<xsl:param name="labelstack" select="substring($labelstack, 2)"/>
<xsl:param name="labelcounter"/>
<xsl:choose>
<xsl:when test="string-length($labeltest) = 0">
<xsl:copy>
<xsl:value-of select="substring(., 2, string-length(.) - 1)"/>
</xsl:copy>
</xsl:when>
<xsl:when test="$labeltest = '('">
<xsl:variable name="labelcounter" select="$labelcounter + 1"/>
<xsl:choose>
<xsl:when test="$labelcounter != 0">
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$labeltest = ')'">
<xsl:variable name="labelcounter" select="$labelcounter - 1"/>
<xsl:choose>
<xsl:when test="$labelcounter != 0">
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:function name="mf:nested-characters" as="xs:boolean">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="pair" as="xs:string*"/>
<xsl:sequence select="mf:match-pairs(string-to-codepoints($input), string-to-codepoints($pair[1]), string-to-codepoints($pair[2]), 0)"/>
</xsl:function>
<xsl:function name="mf:match-pairs" as="xs:boolean">
<xsl:param name="input" as="xs:integer*"/>
<xsl:param name="open" as="xs:integer"/>
<xsl:param name="close" as="xs:integer"/>
<xsl:param name="count" as="xs:integer"/>
<xsl:sequence select="
if (not(exists($input)))
then $count eq 0
else if ($input[1] eq $open)
then mf:match-pairs(subsequence($input, 2), $open, $close, $count + 1)
else if ($input[1] eq $close)
then (if ($count eq 1 and exists($input[2]))
then false()
else mf:match-pairs(subsequence($input, 2), $open, $close, $count - 1))
else mf:match-pairs(subsequence($input, 2), $open, $close, $count)"/>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="label[matches(., '^\(.*\)$')][mf:nested-characters(., ('(', ')'))]">
<xsl:copy>
<xsl:value-of select="replace(., '^\(|\)$', '')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
变换
<root>
<label>(label (1))</label>
<label>(label) (1)</label>
<label>(1)</label>
<label>(This is)(a (label))</label>
<label>(This (is) (a label))</label>
</root>
进入
<root>
<label>label (1)</label>
<label>(label) (1)</label>
<label>1</label>
<label>(This is)(a (label))</label>
<label>This (is) (a label)</label>
</root>
我正在使用 XSLT 从标签中删除括号,但仅当它们位于开头和结尾时,并且仅当链接时。
例如
(标签(1))变成标签(1)
但是
(标签) (1) 仍然是 (标签) (1)
具体编辑
更多示例:
(1) 变成 1
(这是)(一个(标签))仍然是(这是)(一个(标签))
(This (is) (a label)) 变成 This (is) (a label)
两者之间有任何变化
我认为我有一个解决方案,方法是依次测试字符并保留一个计数器来跟踪它们是否已链接,但我仍然遗漏了一些东西。感谢任何帮助。
这是我当前的代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes" method="xml" doctype-system="\ukfs11\Bks_RAPS\XML\DTDs\TFB\TFB.dtd"/>
<xsl:param name="labelstack"/>
<xsl:param name="labeltest"/>
<xsl:template match="//label[matches(.,'^\(.*\)$')]">
<xsl:param name="labelstack" select="substring(., 1, string-length(.) - 1)"/>
<xsl:param name="labelcounter"/>
<xsl:call-template name="loop1">
<xsl:with-param name="labelstack" select="$labelstack"/>
<xsl:with-param name="labelcounter" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="loop1">
<xsl:param name="labeltest" select="substring($labelstack, 1,1)"/>
<xsl:param name="labelstack" select="substring($labelstack, 2)"/>
<xsl:param name="labelcounter"/>
<xsl:choose>
<xsl:when test="string-length($labeltest) = 0">
<xsl:copy>
<xsl:value-of select="substring(., 2, string-length(.) - 1)"/>
</xsl:copy>
</xsl:when>
<xsl:when test="$labeltest = '('">
<xsl:variable name="labelcounter" select="$labelcounter + 1"/>
<xsl:choose>
<xsl:when test="$labelcounter != 0">
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$labeltest = ')'">
<xsl:variable name="labelcounter" select="$labelcounter - 1"/>
<xsl:choose>
<xsl:when test="$labelcounter != 0">
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="loop1">
<xsl:with-param name="labelcounter" select="$labelcounter"/>
<xsl:with-param name="labelstack" select="$labelstack"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:function name="mf:nested-characters" as="xs:boolean">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="pair" as="xs:string*"/>
<xsl:sequence select="mf:match-pairs(string-to-codepoints($input), string-to-codepoints($pair[1]), string-to-codepoints($pair[2]), 0)"/>
</xsl:function>
<xsl:function name="mf:match-pairs" as="xs:boolean">
<xsl:param name="input" as="xs:integer*"/>
<xsl:param name="open" as="xs:integer"/>
<xsl:param name="close" as="xs:integer"/>
<xsl:param name="count" as="xs:integer"/>
<xsl:sequence select="
if (not(exists($input)))
then $count eq 0
else if ($input[1] eq $open)
then mf:match-pairs(subsequence($input, 2), $open, $close, $count + 1)
else if ($input[1] eq $close)
then (if ($count eq 1 and exists($input[2]))
then false()
else mf:match-pairs(subsequence($input, 2), $open, $close, $count - 1))
else mf:match-pairs(subsequence($input, 2), $open, $close, $count)"/>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="label[matches(., '^\(.*\)$')][mf:nested-characters(., ('(', ')'))]">
<xsl:copy>
<xsl:value-of select="replace(., '^\(|\)$', '')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
变换
<root>
<label>(label (1))</label>
<label>(label) (1)</label>
<label>(1)</label>
<label>(This is)(a (label))</label>
<label>(This (is) (a label))</label>
</root>
进入
<root>
<label>label (1)</label>
<label>(label) (1)</label>
<label>1</label>
<label>(This is)(a (label))</label>
<label>This (is) (a label)</label>
</root>