这个有点棘手,我已经坚持了一段时间。我想做的是用标签代替括号'['(例如按钮,链接等),代替']'
<section>
<title>Buttons</title>
<orderedlist>
<listitem>
<para>Clicking on [Save] will attempt to save changes, then it navigates to <xref linkend="saved" xrefstyle="select: title"/>.</para>
</listitem>
<listitem>
<para>Clicking on [Cancel] navigates to <xref linkend="noSave" xrefstyle="select: title"/>.</para>
</listitem>
</orderedlist>
</section>
要:
<section>
<title>Buttons</title>
<orderedlist>
<listitem>
<para>Clicking on <uicontrol>Save</uicontrol> will attempt to save changes, then it navigates to <xref linkend="saved" xrefstyle="select: title"/>.</para>
</listitem>
<listitem>
<para>Clicking on <uicontrol>Cancel</uicontrol> navigates to <xref linkend="noSave" xrefstyle="select: title"/>.</para>
</listitem>
</orderedlist>
</section>
并且'['']'不一定总是在section.listitem.para
中编辑:当括号中的某些字词时,我只需要替换[]。
答案 0 :(得分:3)
对于嵌套括号没有嵌套uicontrol
(需要解析平衡括号而不是平衡括号)。
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" name="replace" priority="1">
<xsl:param name="pString" select="."/>
<xsl:variable name="vMask" select="translate($pString,
translate($pString,
'[]',
''),
'')"/>
<xsl:choose>
<xsl:when test="contains($vMask,'[]')">
<xsl:call-template name="makeControl">
<xsl:with-param name="pString" select="$pString"/>
<xsl:with-param name="pMask"
select="substring-before($vMask,'[]')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pString"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="makeControl">
<xsl:param name="pString"/>
<xsl:param name="pMask"/>
<xsl:choose>
<xsl:when test="$pMask">
<xsl:variable name="vMask" select="substring($pMask,1,1)"/>
<xsl:value-of select="concat(
substring-before(
$pString,
$vMask),
$vMask)"/>
<xsl:call-template name="makeControl">
<xsl:with-param name="pString"
select="substring-after($pString,$vMask)"/>
<xsl:with-param name="pMask" select="substring($pMask,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($pString,'[')"/>
<uicontrol>
<xsl:value-of select="substring-before(
substring-after(
$pString,
'['),
']')"/>
</uicontrol>
<xsl:call-template name="replace">
<xsl:with-param name="pString"
select="substring-after($pString,']')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
输出:
<section>
<title>Buttons</title>
<orderedlist>
<listitem>
<para>Clicking on <uicontrol>Save</uicontrol> will attempt to save changes, then it navigates to <xref linkend="saved" xrefstyle="select: title"></xref>.</para>
</listitem>
<listitem>
<para>Clicking on <uicontrol>Cancel</uicontrol> navigates to <xref linkend="noSave" xrefstyle="select: title"></xref>.</para>
</listitem>
</orderedlist>
</section>
有了这个输入:
<text>
This is an opening bracket [ ? [Yes] [No]
This is a closing bracket ] ? [Yes] [No]
</text>
输出:
<text>
This is an opening bracket [ ? <uicontrol>Yes</uicontrol> <uicontrol>No</uicontrol>
This is a closing bracket ] ? <uicontrol>Yes</uicontrol> <uicontrol>No</uicontrol>
</text>
注意:任何匹配\[[^\[\]]*\]
的文字都会被包含在uicontrol
元素中。
答案 1 :(得分:2)
您可以使用contains
,substring-before
和substring-after
函数查找括号,然后根据需要插入元素而不是括号。
编辑 - 应该有效:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template name="insertElements">
<xsl:param name="text" select="." />
<xsl:choose>
<xsl:when test="contains($text, '[')">
<xsl:value-of select="substring-before($text, '[')"/>
<xsl:variable name="after" select="substring-after($text, '[')" />
<uicontrol>
<xsl:value-of select="substring-before($after, ']')"/>
</uicontrol>
<xsl:call-template name="insertElements">
<xsl:with-param name="text" select="substring-after($after, ']')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="self::text()">
<xsl:call-template name="insertElements" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:uicontrols>
<control>[Save]</control>
<control>[Cancel]</control>
</my:uicontrols>
<xsl:key name="kHasControls" match="text()"
use="boolean(document('')/*/my:uicontrols/*[contains(current(), .)])"/>
<xsl:variable name="vControls" select="document('')/*/my:uicontrols/*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[key('kHasControls', 'true')]">
<xsl:choose>
<xsl:when test="not($vControls[contains(current(),.)])">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="createControl"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="createControl">
<xsl:param name="pText" select="."/>
<xsl:choose>
<xsl:when test="not(contains($pText, '['))">
<xsl:copy-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="substring-before($pText, '[')"/>
<xsl:variable name="vStartText" select=
"concat('[', substring-after($pText, '['))"/>
<xsl:variable name="vCtrl" select="$vControls[starts-with($vStartText,.)]"/>
<xsl:choose>
<xsl:when test="not($vCtrl)">
<xsl:text>[</xsl:text>
<xsl:call-template name="createControl">
<xsl:with-param name="pText" select="substring($vStartText,1)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<uicontrol>
<xsl:value-of select="translate($vCtrl,'[]','')"/>
</uicontrol>
<xsl:call-template name="createControl">
<xsl:with-param name="pText" select="substring-after($vStartText, $vCtrl)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<section>
<title>Buttons</title>
<orderedlist>
<listitem>
<para>Clicking on [Save] will attempt to save changes, then it navigates to <xref linkend="saved" xrefstyle="select: title"/>.</para>
</listitem>
<listitem>
<para>Clicking on [Cancel] navigates to <xref linkend="noSave" xrefstyle="select: title"/>.</para>
</listitem>
</orderedlist>
</section>
生成想要的正确结果:
<section>
<title>Buttons</title>
<orderedlist>
<listitem>
<para>Clicking on <uicontrol>Save</uicontrol><xref linkend="saved" xrefstyle="select: title"/>.</para>
</listitem>
<listitem>
<para>Clicking on <uicontrol>Cancel</uicontrol><xref linkend="noSave" xrefstyle="select: title"/>.</para>
</listitem>
</orderedlist>
</section>
请注意以下:
此解决方案仅替换控件名称的受控列表。通过这种方式,我们可以防止意外错误,并且我们可以自由地使用"[Anything]"
类型的字符串而不会出现任何问题(例如,我们希望显示一个着名的XPath表达式 - 根据定义,这样的表达式具有谓词:))
密钥的使用可确保提高效率,而不是扫描"["
的每个文本节点。