用方括号重新格式化日期

时间:2016-11-30 12:52:41

标签: regex xslt-2.0 square-bracket

将我的XML文件传输到TeX时,我尝试重新格式化日期 - 我的出版商说我必须在日期之间使用较小的水平空间 - 并且无法超越第一步。

我的输入文件是

<a>
<date>January 1900</date>
<date>2. 2. 1902</date>
<date>3. [3]. 1903</date>
<date>[4. 4. 1904]</date>
</a>

其中括号表示日期不确定。有可能的括号组合,例如年度第二个数字:1 [9] 00。我创建了一个命令\ mini,它在TeX中创建了小空间: \ newcommand {\迷你} {\} xslt之后的结果应为:

January 1900
2.{\mini}2.{\mini}1902
3.{\mini}[3].{\mini}1903
[4.{\mini}4.{\mini}1904]

我编写了一个函数,它试图提取方括号并将它们的位置存储到变量中,然后再将它们连接起来。但由于我没有设法让变量显示正确的位置,我陷入了困境:

<xsl:function name="foo:date-translate">
      <xsl:param name="date-string" as="xs:string"/>
      <xsl:variable name="opening-square-bracket" as="xs:integer" select="count(substring-before($date-string,'&#91;'))"/>
      <xsl:variable name="closing-square-bracket" as="xs:integer" select="count(substring-before($date-string,'&#x5b;'))"/>
      <xsl:variable name="date-string-without-square-brackets" as="xs:string" select="replace(replace($date-string,'\[',''),'\]','')"/>
      <xsl:choose>
      <xsl:when test="matches($date-string-without-square-brackets,'\d{1,2}. \d{1,2}. \d{4}')">
         <xsl:choose>
            <xsl:when test="not(contains($date-string,'['))"> 
               <xsl:value-of select="replace($date-string,'(\d{1,2}). (\d{1,2}). (\d{4})','$1\\mini$2\\mini$3')"/>
            </xsl:when>
            <xsl:otherwise> 
               <xsl:value-of select="concat(substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','$1\\mini$2\\mini$3'),0,$opening-square-bracket),'[',substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','$1\\mini$2\\mini$3'),$opening-square-bracket, $closing-square-bracket))"/>
            </xsl:otherwise>
         </xsl:choose>
          </xsl:when>
         <xsl:otherwise>
               <xsl:value-of select="$date-string"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:function>

1 个答案:

答案 0 :(得分:0)

我终于设法通过递归来解决它。基本上我测试它是否适合正则表达式dd。毫米。 yyyy删除括号时。因为这样可以重建整个字符串。

<xsl:function name="foo:date-repeat">
      <xsl:param name="date-string" as="xs:string"/>
      <xsl:param name="amount" as="xs:integer"/>
      <xsl:param name="counter" as="xs:integer"/>
      <xsl:choose>
         <xsl:when test="substring($date-string,$counter,1) =' '">
            <xsl:text>\mini</xsl:text>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="substring($date-string,$counter,1)"/>
         </xsl:otherwise>
      </xsl:choose>
      <xsl:if test="$counter &lt;= $amount">
         <xsl:value-of select="foo:date-repeat($date-string, $amount,$counter+1)"/>
      </xsl:if>
   </xsl:function>



 <xsl:function name="foo:date-translate">
      <xsl:param name="date-string" as="xs:string"/>
      <xsl:variable name="date-string-without-square-brackets" as="xs:string" select="replace(replace($date-string,'\[',''),'\]','')"/>
      <xsl:choose>
      <xsl:when test="matches($date-string-without-square-brackets,'\d{1,2}. \d{1,2}. \d{4}')">
         <xsl:choose>
            <xsl:when test="not(contains($date-string,'['))"> <!-- Daten ohne eckige Klammer -->
               <xsl:value-of select="replace($date-string,'(\d{1,2}). (\d{1,2}). (\d{4})','$1\\mini$2\\mini$3')"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="foo:date-repeat($date-string, string-length($date-string),1)"/>
            </xsl:otherwise>
         </xsl:choose>
          </xsl:when>
         <xsl:otherwise>
               <xsl:value-of select="$date-string"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:function>

我甚至扩展了我的解决方案,现在功能检查测试每个空间&#39; &#39;如果之前是点或点和括号,之后是数字或括号和数字:

<xsl:function name="foo:date-repeat">
  <xsl:param name="date-string" as="xs:string"/>
  <xsl:param name="amount" as="xs:integer"/>
  <xsl:param name="counter" as="xs:integer"/>
  <xsl:choose> 
     <xsl:when test="substring($date-string,$counter,1) =' ' and ((substring($date-string,$counter -1,1) = '.' and number(substring($date-string,$counter -2,1)) = number(substring($date-string,$counter -2,1))) or (substring($date-string,$counter -2,2) = '.]' and number(substring($date-string,$counter -3,1)) = number(substring($date-string,$counter -3,1))))">
        <xsl:choose>
           <xsl:when test="number(substring($date-string,$counter +1,1)) = number(substring($date-string,$counter +1,1))">
              <xsl:text>\mini</xsl:text>
           </xsl:when>
           <xsl:when test="substring($date-string,$counter +1,1) ='[' and number(substring($date-string,$counter +2,1)) = number(substring($date-string,$counter +2,1))">
              <xsl:text>\mini</xsl:text>
           </xsl:when>
           <xsl:otherwise>
              <xsl:value-of select="substring($date-string,$counter,1)"/>
           </xsl:otherwise>
        </xsl:choose>
     </xsl:when>
     <xsl:when test="substring($date-string,$counter,1) ='['">
        <xsl:text>{[}</xsl:text>
     </xsl:when>
     <xsl:when test="substring($date-string,$counter,1) =']'">
        <xsl:text>{]}</xsl:text>
     </xsl:when>
     <xsl:otherwise>
        <xsl:value-of select="substring($date-string,$counter,1)"/>
     </xsl:otherwise>
  </xsl:choose>
  <xsl:if test="$counter &lt;= $amount">
     <xsl:value-of select="foo:date-repeat($date-string, $amount,$counter+1)"/>
  </xsl:if>