1

我需要根据给定的分隔符属性使用 XSLT 1.0 转换以下编码。文本应根据给定的分隔符进行分隔:

输入:

<chapter xmlns="http://www.w3.org/1998/Math/MathML">
<math display="inline"><mfenced separators=", : . ;"><mn>1</mn><mtext>b</mtext><mo>%</mo><mi>d</mi><mi>e</mi></mfenced></math>
<math display="inline"><mfenced separators=", ;"><mi>a</mi><mi>b</mi><mi>c</mi><mi>d</mi><mi>e</mi></mfenced></math>
<math display="inline"><mfenced separators=", : . ; ; : . ;"><mi>a</mi><mi>b</mi><mi>c</mi><mi>d</mi><mi>e</mi></mfenced></math>
</chapter>

需要输出:

1,b:%.d;e
a,b;c;d;e
a,b:c.d;e

另请注意,如果分隔符太多,多余的将被忽略。如果给出了分隔符,但太少,则根据需要重复最后一个

仅当分隔符小于子元素时,我才能获得输出。

XSLT 1.0 试过:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML">

<xsl:template match="m:mfenced">
<xsl:variable name="text" select="@separators"/>
<xsl:for-each select="child::*">
<xsl:apply-templates/>
<xsl:choose>
<xsl:when test="contains($text,' ')">
<xsl:variable name="attr" select="string-length(translate($text, ' ', ''))"/>
<xsl:variable name="ch" select="count(parent::*/child::*)-1"/>
<xsl:if test="$ch=$attr"><xsl:value-of select="substring($text,count(preceding-sibling::*)+position(),1)"/></xsl:if>

<xsl:if test="$ch gt $attr">
<xsl:if test="not(substring($text,count(preceding-sibling::*)+position(),1)='')"><xsl:value-of select="substring($text,count(preceding-sibling::*)+position(),1)"/></xsl:if>
<xsl:if test="(substring($text,count(preceding-sibling::*)+position(),1)='')"><xsl:value-of select="substring($text,count(preceding-sibling::*)+1,1)"/></xsl:if>
</xsl:if>

<xsl:if test="$ch lt $attr and count(following-sibling::*)>0"><xsl:value-of select="substring($text,count(preceding-sibling::*)+position(),1)"/></xsl:if>
</xsl:when>
<xsl:otherwise><xsl:if test="count(following-sibling::*)>0"><xsl:value-of select="$text"/></xsl:if></xsl:otherwise></xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
4

1 回答 1

3

下面的解决方案是基于获取每个<m:mi>在<m:fenced>元素中的位置来获取下一个要输出的算子。

笔记。我假设用于表示每个运算符的字符串长度为 1。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML">

    <xsl:output method="text" />

    <!-- Ignore all text nodes (just for demo) -->
    <xsl:template match="text()" />

    <xsl:template match="m:mfenced">
        <!-- Print children values and operators -->
        <xsl:apply-templates select="*" mode="list-op">
            <xsl:with-param name="separator-str" select="@separators" />
            <xsl:with-param name="separator-len" select="string-length(@separators)" />
        </xsl:apply-templates>
        <!-- Print new line -->
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <!-- Last m:mi elements for each m:mfenced are just printed -->
    <xsl:template match="*[last()]" mode="list-op">
        <xsl:value-of select="."/>
    </xsl:template>

    <!-- In this template we use the position() function to calculate the next
         operator that is going to be outputted -->
    <xsl:template match="*" mode="list-op">
        <xsl:param name="separator-str" />
        <!-- This parameter is not required, but allows us to cache
             the length of the separators string instead of calculating it
             for each m:mi element -->
        <xsl:param name="separator-len" />

        <!-- Print current value -->
        <xsl:value-of select="." />

        <!-- Calculate the separator position within the string -->
        <xsl:variable name="string-position" select="2*position() - 1" />

        <!-- Check if the position oveflows the position in the array, and
             if it does, print the last separator in the string. -->
        <xsl:choose>
            <xsl:when test="$separator-len >= $string-position">
                <xsl:value-of select="substring($separator-str, $string-position, 1)" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="substring($separator-str, $separator-len)" />
            </xsl:otherwise>
        </xsl:choose>

    </xsl:template>
</xsl:stylesheet>
于 2013-02-22T11:14:21.153 回答