2017-06-05 41 views
0

請建議,如何到達內m /莫包含括號。如何到達相同名稱和格式的嵌套子元素

在給定的樣本中,當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> 

回答

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

感謝您的建議,加上一個不錯的分組方法。 –

+0

有一個疑問先生,爲什麼第二個MROW也是一個孩子,爲什麼它沒有在-for-each-select中達到=「*」。請建議。 –

+0

您的問題與我的XSLT代碼有關嗎?還是問你的問題?如果您有我的建議無效的輸入樣本,請考慮編輯您的問題並顯示它。 –

相關問題