2017-01-31 6 views
1

XMLをTeXに転送するXSLTカスケードがあります。最後のステップでは、2つのタグの間にすべてのテキストを含む単純なxmlファイルがあり、いくつかの検索と置換ルーチンを適用したいと思います。XSLTで句読点を検索して置き換えます

したがって、このような入力ファイル:このXSLTを適用

<start> 
    .– 
    ,– 
    {– 
</start> 

(多かれ少なかれそのままReplacing strings in various XML filesから取られた)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:param name="list"> 
     <words> 
      <word> 
      <search>/</search> 
      <replace>\allowbreak\,\slash\,\allowbreak{}</replace> 
     </word> 
     <word> 
      <search>.–</search> 
      <replace>{\dotdash}</replace> 
     </word> 
     <word> 
      <search>,–</search> 
      <replace>{\commadash}</replace> 
     </word> 
     <word> 
      <search>;–</search> 
      <replace>{\semicolondash}</replace> 
     </word> 
     <word> 
      <search>!–</search> 
      <replace>{\excdash}</replace> 
     </word> 
     </words> 
    </xsl:param> 

    <xsl:template match="@*|*|comment()|processing-instruction()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()"> 
     <xsl:variable name="search" select="concat('(',string-join($list/words/word/search,'|'),')')"/> 
     <xsl:analyze-string select="." regex="{$search}"> 
      <xsl:matching-substring> 
       <xsl:value-of select="$list/words/word[search=current()]/replace"/> 
      </xsl:matching-substring> 
      <xsl:non-matching-substring> 
       <xsl:value-of select="."/> 
      </xsl:non-matching-substring> 
     </xsl:analyze-string> 
    </xsl:template> 
</xsl:stylesheet> 

は、以下の出力しておく必要があります

\ dotdash {}

\ commadash {}

{ - 残念ながら

は "{ - " 何かをトリガするようだと消えます。なぜ誰かが説明できますか?

答えて

1

喜んでオリジナルの答えをあなたにリンクしました。あなたがまだ持っていないなら、upvotingを検討してください。 ;-)

問題は.は正規表現では特別です。したがって、<search>.–</search>は任意の文字と一致し、その後には-が続きます。

あなたの検索変数に.をエスケープする必要があります

<xsl:variable name="search" select="replace(concat('(',string-join($list/words/word/search,'|'),')'),'\.','\\.')"/> 

あなたはその部分を容易にするためにxsl:functionを作成することを検討可能性があるので、あなたは、同様に他の特別な正規表現の文字をエスケープする必要があります。

ここ

...まず第 .{をエスケープする関数の例です
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:so="stackoverflow example" exclude-result-prefixes="so"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:param name="list"> 
    <words> 
     <word> 
     <search>/</search> 
     <replace>\allowbreak\,\slash\,\allowbreak{}</replace> 
     </word> 
     <word> 
     <search>.–</search> 
     <replace>{\dotdash}</replace> 
     </word> 
     <word> 
     <search>,–</search> 
     <replace>{\commadash}</replace> 
     </word> 
     <word> 
     <search>;–</search> 
     <replace>{\semicolondash}</replace> 
     </word> 
     <word> 
     <search>!–</search> 
     <replace>{\excdash}</replace> 
     </word> 
     <!--<word> 
     <search>{–</search> 
     <replace>bam!</replace> 
     </word>--> 
    </words> 
    </xsl:param> 

    <xsl:function name="so:escapeRegex"> 
    <xsl:param name="regex"/> 
    <xsl:analyze-string select="$regex" regex="\.|\{{"> 
     <xsl:matching-substring> 
     <xsl:value-of select="concat('\',.)"/> 
     </xsl:matching-substring> 
     <xsl:non-matching-substring> 
     <xsl:value-of select="."/> 
     </xsl:non-matching-substring> 
    </xsl:analyze-string> 
    </xsl:function> 

    <xsl:template match="@*|*|comment()|processing-instruction()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()"> 
    <xsl:variable name="search" select="so:escapeRegex(concat('(',string-join($list/words/word/search,'|'),')'))"/> 
    <xsl:analyze-string select="." regex="{$search}"> 
     <xsl:matching-substring> 
     <xsl:message>"<xsl:value-of select="."/>" matched <xsl:value-of select="$search"/></xsl:message> 
     <xsl:value-of select="$list/words/word[search=current()]/replace"/> 
     </xsl:matching-substring> 
     <xsl:non-matching-substring> 
     <xsl:value-of select="."/> 
     </xsl:non-matching-substring> 
    </xsl:analyze-string> 
    </xsl:template> 
</xsl:stylesheet> 

あなたlistのparamで最後wordのコメントを解除した場合、それはあなたの例では{–に置き換えられます。

+0

XSLT 3.0では、flags = "q"を使用すると、正規表現内のすべての文字を自分自身を表すものとして扱うことができます。しかしもちろん、あなたは "|"代替案を分離する。 –

関連する問題