Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT替换单个元素中的多个字符_Xslt - Fatal编程技术网

使用XSLT替换单个元素中的多个字符

使用XSLT替换单个元素中的多个字符,xslt,Xslt,我需要找到一个实体并将其替换为字符串。例如, 应替换为'空白,$应替换为| doll |,%应替换为|perc |。我可以使用XSLT1.0 XML文档: <?xml version="1.0"?> <chapter> <math> <mtext>This is&#x00A0;$400, 300%to500%.</mtext> </math> </chapter> 这是 $40

我需要找到一个实体并将其替换为字符串。例如,
 
应替换为
'
空白,
$
应替换为
| doll |
%
应替换为
|perc |
。我可以使用XSLT1.0

XML文档:

<?xml version="1.0"?>
<chapter>
<math>
<mtext>This is&#x00A0;$400, 300%to500%.</mtext>
</math>
</chapter>

这是 $400,300%到500%。
XSLT1.0转换已尝试:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="mtext">
<mtext>
    <xsl:choose>
<xsl:when test="contains(.,'&#x00A0;') or contains(.,'$') or contains(.,'%')">
<xsl:if test="contains(.,'&#x00A0;')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="."/><xsl:with-param name="from">&#x00A0;</xsl:with-param><xsl:with-param name="to" select="' '"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'$')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">$</xsl:with-param><xsl:with-param name="to" select="'|doll|'"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'%')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">%</xsl:with-param><xsl:with-param name="to" select="'|perc|'"/></xsl:call-template></xsl:if>
</xsl:when>
<xsl:otherwise>
                <xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</mtext>
</xsl:template>


<xsl:template name="replace-string">
    <xsl:param name="text"/>
    <xsl:param name="from"/>
    <xsl:param name="to"/>
    <xsl:choose>
      <xsl:when test="contains($text, $from)">
        <xsl:variable name="before" select="substring-before($text, $from)"/>
        <xsl:variable name="after" select="substring-after($text, $from)"/>
        <xsl:variable name="prefix" select="concat($before, $to)"/>
        <xsl:copy-of select="$before"/>
          <xsl:value-of select="$to" disable-output-escaping="yes"/>
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="$after"/>
          <xsl:with-param name="from" select="$from"/>
          <xsl:with-param name="to" select="$to"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
<?xml version='1.0' ?>
<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext>
<chapter>
    <math>
        <mtext>This is&#x00A0;$400, 300%to500%.</mtext>
    </math>
</chapter>

 ;
$
%
所需输出:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="mtext">
<mtext>
    <xsl:choose>
<xsl:when test="contains(.,'&#x00A0;') or contains(.,'$') or contains(.,'%')">
<xsl:if test="contains(.,'&#x00A0;')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="."/><xsl:with-param name="from">&#x00A0;</xsl:with-param><xsl:with-param name="to" select="' '"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'$')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">$</xsl:with-param><xsl:with-param name="to" select="'|doll|'"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'%')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">%</xsl:with-param><xsl:with-param name="to" select="'|perc|'"/></xsl:call-template></xsl:if>
</xsl:when>
<xsl:otherwise>
                <xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</mtext>
</xsl:template>


<xsl:template name="replace-string">
    <xsl:param name="text"/>
    <xsl:param name="from"/>
    <xsl:param name="to"/>
    <xsl:choose>
      <xsl:when test="contains($text, $from)">
        <xsl:variable name="before" select="substring-before($text, $from)"/>
        <xsl:variable name="after" select="substring-after($text, $from)"/>
        <xsl:variable name="prefix" select="concat($before, $to)"/>
        <xsl:copy-of select="$before"/>
          <xsl:value-of select="$to" disable-output-escaping="yes"/>
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="$after"/>
          <xsl:with-param name="from" select="$from"/>
          <xsl:with-param name="to" select="$to"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
<?xml version='1.0' ?>
<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext>
<chapter>
    <math>
        <mtext>This is&#x00A0;$400, 300%to500%.</mtext>
    </math>
</chapter>

这是| doll | 400300 | perc |到500 | perc |。

此XSLT 1.0转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" extension-element-prefixes="xsl">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:reps>
  <rep>
    <old>&#x00A0;</old>
    <new xml:space="preserve"> </new>
  </rep>
  <rep>
    <old>$</old>
    <new>|doll|</new>
  </rep>
  <rep>
    <old>%</old>
    <new>|perc|</new>
  </rep>
 </my:reps>

 <xsl:variable name="vReps" select="document('')/*/my:reps/*"/>

 <xsl:template match="mtext">
     <xsl:copy>
       <xsl:call-template name="multiReplace"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template name="multiReplace">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pRep" select="$vReps[1]"/>

  <xsl:choose>
    <xsl:when test="not($pRep)"><xsl:value-of select="$pText"/></xsl:when>
      <xsl:otherwise>
        <xsl:variable name="vReplaced">
            <xsl:call-template name="replace">
              <xsl:with-param name="pText" select="$pText"/>
              <xsl:with-param name="pOld" select="$pRep/old"/>
              <xsl:with-param name="pNew" select="$pRep/new"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:call-template name="multiReplace">
         <xsl:with-param name="pText" select="$vReplaced"/>
         <xsl:with-param name="pRep" select="$pRep/following-sibling::*[1]"/>
        </xsl:call-template>
      </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <xsl:template name="replace">
   <xsl:param name="pText"/>
   <xsl:param name="pOld"/>
   <xsl:param name="pNew"/>

   <xsl:if test="$pText">
     <xsl:value-of select="substring-before(concat($pText,$pOld), $pOld)"/>
       <xsl:if test="contains($pText, $pOld)">
         <xsl:value-of select="$pNew"/>
             <xsl:call-template name="replace">
               <xsl:with-param name="pText" select="substring-after($pText, $pOld)"/>
               <xsl:with-param name="pOld" select="$pOld"/>
               <xsl:with-param name="pNew" select="$pNew"/>
             </xsl:call-template>
       </xsl:if>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>
<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext>

 ;
$
|玩偶|
%
|perc|
应用于提供的XML文档时:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="mtext">
<mtext>
    <xsl:choose>
<xsl:when test="contains(.,'&#x00A0;') or contains(.,'$') or contains(.,'%')">
<xsl:if test="contains(.,'&#x00A0;')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="."/><xsl:with-param name="from">&#x00A0;</xsl:with-param><xsl:with-param name="to" select="' '"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'$')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">$</xsl:with-param><xsl:with-param name="to" select="'|doll|'"/></xsl:call-template><xsl:variable name="mtext_text" select="."/></xsl:if>
<xsl:variable name="mtext_text" select="."/>
<xsl:if test="contains(.,'%')"><xsl:call-template name="replace-string"><xsl:with-param name="text" select="mtext_text"/><xsl:with-param name="from">%</xsl:with-param><xsl:with-param name="to" select="'|perc|'"/></xsl:call-template></xsl:if>
</xsl:when>
<xsl:otherwise>
                <xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</mtext>
</xsl:template>


<xsl:template name="replace-string">
    <xsl:param name="text"/>
    <xsl:param name="from"/>
    <xsl:param name="to"/>
    <xsl:choose>
      <xsl:when test="contains($text, $from)">
        <xsl:variable name="before" select="substring-before($text, $from)"/>
        <xsl:variable name="after" select="substring-after($text, $from)"/>
        <xsl:variable name="prefix" select="concat($before, $to)"/>
        <xsl:copy-of select="$before"/>
          <xsl:value-of select="$to" disable-output-escaping="yes"/>
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="$after"/>
          <xsl:with-param name="from" select="$from"/>
          <xsl:with-param name="to" select="$to"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
<?xml version='1.0' ?>
<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext>
<chapter>
    <math>
        <mtext>This is&#x00A0;$400, 300%to500%.</mtext>
    </math>
</chapter>

这是 $400,300%到500%。
生成所需的正确结果

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" extension-element-prefixes="xsl">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:reps>
  <rep>
    <old>&#x00A0;</old>
    <new xml:space="preserve"> </new>
  </rep>
  <rep>
    <old>$</old>
    <new>|doll|</new>
  </rep>
  <rep>
    <old>%</old>
    <new>|perc|</new>
  </rep>
 </my:reps>

 <xsl:variable name="vReps" select="document('')/*/my:reps/*"/>

 <xsl:template match="mtext">
     <xsl:copy>
       <xsl:call-template name="multiReplace"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template name="multiReplace">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pRep" select="$vReps[1]"/>

  <xsl:choose>
    <xsl:when test="not($pRep)"><xsl:value-of select="$pText"/></xsl:when>
      <xsl:otherwise>
        <xsl:variable name="vReplaced">
            <xsl:call-template name="replace">
              <xsl:with-param name="pText" select="$pText"/>
              <xsl:with-param name="pOld" select="$pRep/old"/>
              <xsl:with-param name="pNew" select="$pRep/new"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:call-template name="multiReplace">
         <xsl:with-param name="pText" select="$vReplaced"/>
         <xsl:with-param name="pRep" select="$pRep/following-sibling::*[1]"/>
        </xsl:call-template>
      </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <xsl:template name="replace">
   <xsl:param name="pText"/>
   <xsl:param name="pOld"/>
   <xsl:param name="pNew"/>

   <xsl:if test="$pText">
     <xsl:value-of select="substring-before(concat($pText,$pOld), $pOld)"/>
       <xsl:if test="contains($pText, $pOld)">
         <xsl:value-of select="$pNew"/>
             <xsl:call-template name="replace">
               <xsl:with-param name="pText" select="substring-after($pText, $pOld)"/>
               <xsl:with-param name="pOld" select="$pOld"/>
               <xsl:with-param name="pNew" select="$pNew"/>
             </xsl:call-template>
       </xsl:if>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>
<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext>
这是| doll | 400300 | perc |到500 | perc |。

您真的需要为此使用XSLT吗?对于大多数过程语言,您可以在一行代码中轻松完成此操作。@flyn1179我使用XSLT进行转换,我认为可以通过XSLT完成。但最后我不得不决定选择其他语言来代替这个