2017-06-05 1 views
0

Veuillez suggérer, comment atteindre le mrow interne/mo contient des accolades.Comment atteindre les éléments enfants imbriqués de même nom et formats

Dans des échantillons donnés, les accolades de premier niveau sont converties en «MFENCED» quand mrow (si son premier et dernier enfant devrait être «MO» avec des signes d'accolades). Mais incapable de modifier les parenthèses de second niveau, où ceux-ci ont aussi 'MFRAC' comme descendant. La correspondance de modèle devrait partir de 'MROW' (comme indiqué).

entrée 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> 

Résultat requis:

<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> 

Répondre

1

Je pense que vous c une utilisation xsl:for-each-group group-starting-with/group-ending-with comme suit:

<?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> 

Cela donne

<?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> 
+0

Merci pour la suggestion, plus un pour agréable groupement méthode. –

+0

Et un doute monsieur, Pourquoi deuxième MROW est aussi un enfant, pourquoi il n'est pas atteint dans -for-each select = "*". Veuillez suggérer. –

+0

Votre question est-elle liée à mon code XSLT? Ou à celui de votre question? Si vous avez un exemple d'entrée pour lequel ma suggestion ne fonctionne pas, pensez à modifier votre question et à la montrer. –