XSL:用xml标签替换某些字符

Ace*_*Ace 6 xml xslt replace

这个有点棘手,我已经坚持了一段时间.我想做的是用标签代替括号'['(例如按钮,链接等),代替']'

<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>
Run Code Online (Sandbox Code Playgroud)

至:

<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>
Run Code Online (Sandbox Code Playgroud)

并且'['']'不一定总是在section.listitem.para中

编辑:当括号中的某些单词时,我只需要替换[].

Dim*_*hev 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>
Run Code Online (Sandbox Code Playgroud)

当应用于提供的 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>
Run Code Online (Sandbox Code Playgroud)

产生想要的正确结果

<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>
Run Code Online (Sandbox Code Playgroud)

请注意以下事项

  1. 此解决方案仅替换受控的控件名称列表。通过这种方式,我们可以免受意外错误的影响,而且我们可以自由地使用字符串类型而"[Anything]"不会出现任何问题(例如,我们想要显示一个著名的 XPath 表达式——这样的表达式根据定义有谓词:))

  2. 使用键比扫描每个文本节点可确保更高的效率"["