请建议,如何到达内部的mrow / mo包含大括号。
在给定的样本中,当mrow(如果它的第一个和最后一个孩子应该是带有大括号的'MO')时,第一级括号被转换为'MFENCED'。但无法修改二级括号,其中那些也是'MFRAC'作为后代。模板匹配应来自'MROW'(如给定的)。
XML输入:
<article>
<body>
<math id="m1">
<mrow>
<mo>(</mo><!--first level braces open-->
<mi>u</mi>
<mo>+</mo>
<mi>g</mi>
<mi>=</mi>
<mrow>
<mo>(</mo><!--second level braces open-->
<mfrac>
<mrow><mn>1</mn></mrow>
<mrow><mn>2</mn></mrow>
</mfrac>
<mo>)</mo><!--second level braces close-->
</mrow>
<mo>)</mo><!--first level braces close-->
</mrow>
</math>
<math id="m2">
<mrow>
<mo>(</mo>
<mrow>
<mfrac>
<mn>8</mn>
<mn>9</mn>
</mfrac>
</mrow>
<mo>)</mo>
</mrow>
</math>
</body>
</article>
XSLT 2.0:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="mrow[matches(child::*[1][name()='mo'], '^(\(|\[|\{)$')]
[matches(child::*[position()=last()][name()='mo'], '^(\)|\]|\})$')]">
<xsl:choose>
<xsl:when test="descendant::mfrac">
<xsl:copy>
<xsl:element name="mfenced">
<xsl:attribute name="open"><xsl:value-of select="child::*[1][name()='mo']"/></xsl:attribute>
<xsl:attribute name="close"><xsl:value-of select="child::*[position()=last()][name()='mo']"/></xsl:attribute>
<xsl:for-each select="*">
<xsl:if test="position()=1"/>
<xsl:if test="not(position()=1) and not(position()=last())">
<xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:if>
<xsl:if test="position()=last()"/>
</xsl:for-each>
</xsl:element>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
必填结果:
<article>
<body>
<math id="m1">
<mrow>
<mfenced open="(" close=")"><mi>u</mi><mo>+</mo><mi>g</mi><mi>=</mi>
<mrow>
<mfenced open="(" close=")"><!-- this node or modification required, because, within this MFRAC presents, then it should convert to 'MFENCED' -->
<mfrac>
<mrow><mn>1</mn></mrow>
<mrow><mn>2</mn></mrow>
</mfrac>
</mfenced>
</mrow>
</mfenced>
</mrow>
</math>
<math id="m2">
<mrow>
<mfenced open="(" close=")">
<mrow>
<mfrac>
<mn>8</mn>
<mn>9</mn>
</mfrac>
</mrow>
</mfenced>
</mrow>
</math>
</body>
</article>
答案 0 :(得分:1)
我认为您可以使用xsl:for-each-group group-starting-with/group-ending-with
,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<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:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mrow[mo = '(']">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="mo[. = '(']">
<xsl:choose>
<xsl:when test="self::mo[. = '(']">
<xsl:for-each-group select="current-group() except ." group-ending-with="mo[. = ')']">
<xsl:choose>
<xsl:when test="current-group()[last()][self::mo[. = ')']]">
<mfenced open="(" close=")">
<xsl:apply-templates select="current-group()[not(position() eq last())]"/>
</mfenced>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这给了
<?xml version="1.0" encoding="UTF-8"?>
<article>
<body>
<math id="m1">
<mrow>
<mfenced open="(" close=")">
<mi>u</mi>
<mo>+</mo>
<mi>g</mi>
<mi>=</mi>
<mrow>
<mfenced open="(" close=")">
<mfrac>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</mfrac>
</mfenced>
</mrow>
</mfenced>
</mrow>
</math>
<math id="m2">
<mrow>
<mfenced open="(" close=")">
<mrow>
<mfrac>
<mn>8</mn>
<mn>9</mn>
</mfrac>
</mrow>
</mfenced>
</mrow>
</math>
</body>
</article>