2017-01-31 3 views
1

XML을 TeX로 전송하는 XSLT-cascade가 있습니다. 마지막 단계에서는 두 개의 태그 사이에 모든 텍스트가있는 간단한 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을 만드는 고려할 수 있도록,뿐만 아니라 다른 특수 정규식 문자를 이스케이프해야합니다. 당신이 당신의 list PARAM의 마지막 word 주석을 제거하면

여기

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

... 스타터 .{을 탈출하는 함수의 예입니다, 당신의 예에서 {–을 대체합니다.

+0

XSLT 3.0에서는 정규 표현식의 모든 문자가 자신을 나타내는 것으로 간주되도록 flags = "q"를 사용할 수 있습니다. 하지만 물론 "|"을 사용할 수 없습니다. 대안을 구분할 수 있습니다. –