2013-04-11 99 views
0

我需要查找並替換字符串中的實體和字符。例如, 應替換爲' '空格,$應替換爲|doll|,%應替換爲|perc|。我可以使用XSLT 1.0。使用XSLT替換單個元素中的多個字符

XML文檔:

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

XSLT 1.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> 
+0

你真的需要使用XSLT嗎?你可以用大多數程序語言輕鬆地做到這一點。 – Flynn1179 2013-04-11 14:19:21

+0

@ Flynn1179我正在使用XSLT進行轉換,我認爲可以通過XSLT完成。但最後我不得不決定選擇一些其他語言來取代這個 – siva2012 2013-04-11 14:21:59

回答

1

這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> 

時所提供的XML文檔應用:

<chapter> 
    <math> 
     <mtext>This is&#x00A0;$400, 300%to500%.</mtext> 
    </math> 
</chapter> 

產生想要的,正確的結果

<mtext>This is |doll|400, 300|perc|to500|perc|.</mtext> 
+0

感謝您的幫助 – siva2012 2013-04-11 14:22:30

相關問題