插入空间'下标文本和右括号之间的元素

时间:2015-11-27 17:10:22

标签: xml xslt xslt-2.0

请建议在下标(msub)文本和结束括号')之间插入空格,其中' p'是第一个孩子或第一个孩子的后代文本。 (xsl:模板匹配将包含大括号')'等文本。)

在文本' p'之间插入空格有一些标准。并且关闭括号')。 (在下文中,假设p2)为< sub>< mi> p< / mi>< mn> 2< / mn>< / sub>)。

模板匹配必须来自' mo'它包含右括号')' 。请参阅注释(忽略这些)以解释所需的结果。请建议。

  • p2) - 至 p2< space />) - ' p2'和')',' p'是' msub'的第一个子文本。或下标文本。
  • p2 + a) - 至 p2 + a< space />) - ' p2 + a'之间所需的空间和')',需要空间,因为' p'是' msub'的第一个子文本。或下标文本,剩余文本将出现在下标的第二个文本中。从括号第一个前面的文本属于SUBSCRIPT。

XML:

<article>

<math id="m1">
    <mo>(</mo>
    <msub>
        <mi>p</mi>
        <mn>2</mn>
    </msub>
    <mo>)</mo>
</math>

<math id="m2">
    <mo>(</mo>
    <msub>
        <mrow><mi>r</mi></mrow>
        <mrow><mi>p</mi></mrow>
    </msub>
    <mn>8</mn>
    <mo>)</mo>
</math>

<math id="m3">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn></mrow>
    </msub>
    <mo>)</mo>
</math>

<math id="m4">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mo>)</mo>
</math>

<math id="m5">
    <mo>(</mo>
    <mi>p</mi>
    <mn>2</mn>
    <mi>t</mi>
    <mo>)</mo>
</math>

</article>

XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
        <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:template>

<xsl:template match="mo">
    <xsl:variable name="varPreceded2">
        <xsl:value-of select="preceding::text()[normalize-space(.)!=''][2][generate-id(ancestor::math)=generate-id(current()/ancestor::math)]"/>
    </xsl:variable>

    <xsl:choose>
        <xsl:when test="contains(., ')') and matches($varPreceded2, '^(f|j|p|y|g)$') 
            and 
            preceding::text()[normalize-space(.)!=''][2][generate-id(ancestor::math)=generate-id(current()/ancestor::math)] 
            is 
            (preceding::msub[1]/*[1]/descendant-or-self::*[text()][1])">
            <mspace/><xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

必填结果(用于解释所需结果的评论)

<article>

<math id="m1">
    <mo>(</mo>
    <msub>
        <mi>p</mi>
        <mn>2</mn>
    </msub>
    <mspace/><!-- Here Space required,  because 'before closing bracket first preceded text belongs to MSUB element, and first child of MSUB is having 'p'-->
    <mo>)</mo>
</math>

<math id="m2">
    <mo>(</mo>
    <msub>
        <mrow><mi>r</mi></mrow>
        <mrow><mi>p</mi></mrow>
    </msub>
    <mn>8</mn>
    <!-- Space is not required here, because 'p' is not first child's desendant text, that is second ones-->
    <mo>)</mo>
</math>

<math id="m3">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn></mrow>
    </msub>
    <mspace/><!-- Here Space required,  because 'before closing bracket first preceded text belongs to MSUB element, and first child of MSUB is having  'p'-->
    <mo>)</mo>
</math>

<math id="m4">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mspace/><!-- Here Space required,  because 'before closing bracket first preceded text belongs to MSUB element, and first child of MSUB is having  'p', 'p' is not preceded[2] text, even thou bracket's preceded text is SUBSCRIPT's text where 'p' is first child's text-->
    <mo>)</mo>
</math>

<math id="m5">
    <mo>(</mo>
    <mi>p</mi>
    <mi>t</mi>
    <!-- Space not required because 'p' not a part of SUBSCRIPT -->
    <mo>)</mo>
</math>

</article>

3 个答案:

答案 0 :(得分:1)

好的,从“mo”代替:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"               version="2.0">
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="mo">
        <xsl:if test="contains(., ')') and preceding-sibling::*[1][name()='msub'] and contains(preceding-sibling::msub[1]/child::*[1], 'p')">

            <xsl:comment>Space here</xsl:comment>
            <space/>
        </xsl:if>
        <mo>
            <xsl:apply-templates/>
        </mo>
    </xsl:template>
</xsl:stylesheet>

输出是:

 <article>

<math id="m1">
    <mo>(</mo>
    <msub>
        <mi>p</mi>
        <mn>2</mn>
    </msub>
    <!--Space here--><space/><mo>)</mo>
</math>

<math id="m2">
    <mo>(</mo>
    <msub>
        <mrow><mi>r</mi></mrow>
        <mrow><mi>p</mi></mrow>
    </msub>
    <mn>8</mn>
    <mo>)</mo>
</math>

<math id="m3">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn></mrow>
    </msub>
    <!--Space here--><space/><mo>)</mo>
</math>

<math id="m4">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <!--Space here--><space/><mo>)</mo>
</math>

<math id="m5">
    <mo>(</mo>
    <mi>p</mi>
    <mn>2</mn>
    <mi>t</mi>
    <mo>)</mo>
</math>

</article>

答案 1 :(得分:0)

这个怎么样?我认为在msub上匹配会更容易:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:template>
<xsl:template match="msub">
    <msub>
        <xsl:apply-templates/>
    </msub>


        <xsl:if test="contains(following-sibling::mo,')') and contains(child::*[1],'p')">
            <space/>
        </xsl:if>

</xsl:template>
</xsl:stylesheet>

答案 2 :(得分:0)

借助 generate-id(),我得到了所需的结果......

<强> XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
        <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:template>

<xsl:template match="mo">
  <xsl:variable name="varPreceded">
    <xsl:value-of select="preceding::msub[1]/*[1]/descendant-or-self::text()[1]
      [generate-id(ancestor::math)=generate-id(current()/ancestor::math)]
      [generate-id(current()/preceding::msub[1]/*[2]/descendant-or-self::text()[last()])
         =
       generate-id(current()/preceding::text()[normalize-space(.)!=''][1])]"/>
  </xsl:variable>

    <xsl:choose>
        <xsl:when test="contains(., ')') and matches($varPreceded, '^(f|j|p|y|g)$')">
            <mspace/><xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

<强> XML:

<article>

<math id="m1">
    <mo>(</mo>
    <msub>
        <mi>p</mi>
        <mn>2</mn>
    </msub>
    <mo>)</mo>
</math>

<math id="m2">
    <mo>(</mo>
    <msub>
        <mrow><mi>r2</mi></mrow>
        <mrow><mi>p</mi></mrow>
    </msub>
    <mn>8</mn>
    <mo>)</mo>
</math>

<math id="m3">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn></mrow>
    </msub>
    <mo>)</mo>
</math>

<math id="m4">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mo>)</mo>
</math>

<math id="m5">
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mo>(</mo>
    <mi>p</mi>
    <mn>2</mn>
    <mi>t</mi>
    <mo>)</mo>
</math>

</article>

必填结果:

<article>

<math id="m1">
    <mo>(</mo>
    <msub>
        <mi>p</mi>
        <mn>2</mn>
    </msub>
    <mspace/><mo>)</mo>
</math>

<math id="m2">
    <mo>(</mo>
    <msub>
        <mrow><mi>r2</mi></mrow>
        <mrow><mi>p</mi></mrow>
    </msub>
    <mn>8</mn>
    <mo>)</mo>
</math>

<math id="m3">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn></mrow>
    </msub>
    <mspace/><mo>)</mo>
</math>

<math id="m4">
    <mo>(</mo>
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mspace/><mo>)</mo>
</math>

<math id="m5">
    <msub>
        <mrow><mi>p</mi></mrow>
        <mrow><mn>2</mn><mo>+</mo><mi>s</mi></mrow>
    </msub>
    <mo>(</mo>
    <mi>p</mi>
    <mn>2</mn>
    <mi>t</mi>
    <mo>)</mo>
</math>

</article>