用方括号重新格式化日期
reformatting dates with square brackets
将我的 XML 文件传输到 TeX 时,我尝试重新格式化日期 – 我的出版商说我必须在日期之间使用较小的水平 space – 并且无法超出第一步。
我的输入文件是这个
<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 中使 space 变小:
\newcommand{\mini}{\,}
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,'['))"/>
<xsl:variable name="closing-square-bracket" as="xs:integer" select="count(substring-before($date-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,'['))">
<xsl:value-of select="replace($date-string,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini'),0,$opening-square-bracket),'[',substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini'),$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>
终于用递归解决了。基本上我有测试它是否适合正则表达式 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 <= $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})','\mini\mini')"/>
</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>
我什至扩展了我的解决方案,现在函数检查测试每个 space ' ' 如果之前是一个点或一个点和一个括号,然后是一个数字或一个括号和一个数字:
<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 <= $amount">
<xsl:value-of select="foo:date-repeat($date-string, $amount,$counter+1)"/>
</xsl:if>
将我的 XML 文件传输到 TeX 时,我尝试重新格式化日期 – 我的出版商说我必须在日期之间使用较小的水平 space – 并且无法超出第一步。
我的输入文件是这个
<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 中使 space 变小: \newcommand{\mini}{\,} 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,'['))"/>
<xsl:variable name="closing-square-bracket" as="xs:integer" select="count(substring-before($date-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,'['))">
<xsl:value-of select="replace($date-string,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini'),0,$opening-square-bracket),'[',substring(replace($date-string-without-square-brackets,'(\d{1,2}). (\d{1,2}). (\d{4})','\mini\mini'),$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>
终于用递归解决了。基本上我有测试它是否适合正则表达式 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 <= $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})','\mini\mini')"/>
</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>
我什至扩展了我的解决方案,现在函数检查测试每个 space ' ' 如果之前是一个点或一个点和一个括号,然后是一个数字或一个括号和一个数字:
<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 <= $amount">
<xsl:value-of select="foo:date-repeat($date-string, $amount,$counter+1)"/>
</xsl:if>