2015-01-27 3 views
0

방정식을 첫 번째 점을 기준으로 두 부분으로 나누는 방법을 제안하십시오. 이전에 michael.hor257k의 BREAK 주석 텍스트를 기반으로 suggestion to Split the Equation을 얻었으므로 이제는 기간별로 분할해야합니다.첫 번째 점 (.)을 기준으로 방정식을 분할하십시오.

XML :

<root> 
    <body><sec><title>The sec 1</title><p>Text 1</p></sec></body> 
    <inline-formula> 
     <math display="inline"> 
      <mi>A</mi> 
      <mn>4.651</mn> 
      <mi>The next text</mi> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
      <mrow> 
       <mrow><mi>B</mi></mrow> 
       <mrow><mn>4.651</mn></mrow> 
      </mrow> 
      <mi>The next text</mi> 
     </math> 
    </inline-formula> 
</root> 

XSLT :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="root" select="//inline-formula/*" /> 

    <xsl:template match="/"> 
     <xsl:for-each select="//inline-formula"> 
       <xsl:for-each select="text()"> 
        <xsl:if test="contains(., '.')"> 
         <xsl:apply-templates select="$root"> 
          <xsl:with-param name="i" select="." tunnel="yes"/> 
         </xsl:apply-templates> 
        </xsl:if> 
       </xsl:for-each > 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:param name="i" tunnel="yes"/> 
      <xsl:if test="descendant-or-self::text()[contains(., '.')]"> 
       <xsl:copy> 
        <xsl:apply-templates select="@*|node()"/> 
       </xsl:copy> 
      </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

필수 결과 : 당신이 태어나 셨 이유도

<root> 
    <body><sec><title>The sec 1</title><p>Text 1</p></sec></body> 
    <inline-formula> 
     <math display="inline"> 
      <mi>A</mi> 
      <mn>4.</mn> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
      <!--Text node, before dot is removed --> 
      <mn>651</mn> 
      <mi>The next text</mi> 
     </math> 
    </inline-formula> 

    <inline-formula> 
     <math display="inline"> 
      <mrow> 
       <mrow><mi>B</mi></mrow> 
       <mrow><mn>4.</mn></mrow> 
      </mrow> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
      <mrow> 
       <!--Text node, before dot is removed --> 
       <mrow><mn>651</mn></mrow> 
      </mrow> 
      <mi>The next text</mi> 
     </math> 
    </inline-formula> 
</root> 
+0

및 XSLT 코너를보십시오. _tag 시스템 _을 올바르게 사용하는 법을 배우십시오. XSLT 2.0에 대한 질문은 그와 같이 태그를 붙여야합니다. –

답변

1

michael.hor257k이 제공 한 이전 질문에 대한 답을 살펴보면이 질문에서 사용하는 XSLT와 몇 가지 주요 차이점이 있습니다.의견을 분할 이전의 대답에서, 그러한 의견이 새로운 솔루션에, 당신은 텍스트 노드는 점에서 발생 횟수를 반복해야하는, 그래서

<xsl:for-each select="0 to count(//comment()[.='Break'])"> 

을 표시 횟수를 반복 할

<xsl:if test="descendant-or-self::text()[count(preceding::comment()[.='Break'])=$i]"> 

이 나를 :이 복사 보였다 경우

다음
<xsl:for-each select="0 to count(//text()[contains(., '.')])"> 

는 "정체성"템플릿에, 이전의 대답은보고 현재 노드 아래에 의견의 수를 확인 그러나

<xsl:if test="descendant-or-self::text()[count(preceding::text()[contains(., '.')])=$i]"> 

, 이것은 분할의 첫 부분에 복사 될 수있는 점과 노드로 완전히 정확하지 않을 것이지만, : ANS, 새로운 솔루션, 당신은이 글을 쓰는 것으로 시작 수 분할의 두 번째 부분에는 노드가 전혀 포함되지 않습니다.

<xsl:if test="descendant-or-self::text()[(count(preceding::text()[contains(., '.')])=($i - 1) and contains(., '.')) or count(preceding::text()[contains(., '.')])=$i]"> 

이 분할의 두 부분에 점을 포함하는 노드를 복사합니다 :

필요한 실제로 표현이입니다. 실제로 텍스트를 분할하기 위해 완전히 새로운 템플릿이 필요합니다.

이 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="root" select="/*" /> 

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:copy-of select="*[not(self::inline-formula)]" /> 
     <xsl:for-each select="0 to count(//text()[contains(., '.')])"> 
      <xsl:apply-templates select="$root/inline-formula"> 
       <xsl:with-param name="i" select="." tunnel="yes"/> 
      </xsl:apply-templates> 
     </xsl:for-each > 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="@*"> 
    <xsl:copy /> 
</xsl:template> 

<xsl:template match="node()"> 
    <xsl:param name="i" tunnel="yes"/> 
    <xsl:if test="descendant-or-self::text()[(count(preceding::text()[contains(., '.')])=($i - 1) and contains(., '.')) or count(preceding::text()[contains(., '.')])=$i]"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="text()[contains(., '.')]"> 
    <xsl:param name="i" tunnel="yes"/> 
    <xsl:choose> 
     <xsl:when test="count(preceding::text()[contains(., '.')]) = $i"> 
      <xsl:value-of select="substring-before(., '.')" /><xsl:text>.</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="substring-after(., '.')" /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 
당신이 이제 약간의 시간을 보냈어요
+0

코드에 대한 좋은 제안과 멋진 설명을 보내 주셔서 감사합니다. +1 –

+0

방정식은 두 번째 점이있는 방정식이라도 첫 번째 점, 나머지 점 또는 방정식의 일부만 중단해야합니다. 다음 텍스트. –

+0

인라인 수식 사이에 테스트가 있으면 텍스트 (비 방정식)가 모든 수식 위로 이동합니다. –

1

을 궁금하네요 그러한 변형이 가능하지만 여기에는 가능한 해결책이 있습니다. 규칙이 나에게 명확하지 않습니다.

  • inline-formula에 2 개 이상 mn 개의 요소를 포함 할 수 있습니까?
  • 항상 mn의 문자열 값을 별도의 요소로 분할해야합니까? 아마도 그것의,
  • 당신은 분할 mn의 값에 . 발생한다 말하고 있지만, 여러 점 MathML을

의 단일 mn 요소에 이해가되지 않습니다하지만이 모든 따로 설정 두 가지 개별 변환을 통해 문제를 쉽게 해결할 수 있습니다. 첫 번째는 단순히 mn 요소의 내용을 분리한다 :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="mn[contains(.,'.')]"> 
     <xsl:for-each select="tokenize(.,'\.')"> 
      <mn> 
       <xsl:value-of select="."/> 
       <xsl:if test="position() = 1"> 
        <xsl:text>.</xsl:text> 
       </xsl:if> 
      </mn> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

중간 결과가 다음과 같은 변형 제를 적용,이어서

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <body> 
     <sec> 
     <title>The sec 1</title> 
     <p>Text 1</p> 
     </sec> 
    </body> 
    <inline-formula> 
     <math display="inline"> 
     <mi>A</mi> 
     <mn>4.</mn> 
     <mn>651</mn> 
     <mi>The next text</mi> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
     <mrow> 
      <mrow> 
       <mi>B</mi> 
      </mrow> 
      <mrow> 
       <mn>4.</mn> 
       <mn>651</mn> 
      </mrow> 
     </mrow> 
     <mi>The next text</mi> 
     </math> 
    </inline-formula> 
</root> 

이다. 그런데 특수 모드 키워드 #all#current을 사용하는 것이 좋습니다.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="inline-formula[count(//mn) gt 1]"> 
     <xsl:apply-templates select="." mode="first"/> 
     <xsl:apply-templates select="." mode="second"/> 
    </xsl:template> 

    <xsl:template match="mn[position() = 2] | mi[. = 'The next text']" mode="first"/> 
    <xsl:template match="mi[. != 'The next text']" mode="second"/> 

    <xsl:template match="mn[position() = 1]" mode="second"> 
     <xsl:comment>Text node, before dot is removed</xsl:comment> 
    </xsl:template> 


    <xsl:template match="@*|node()" mode="#all"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" mode="#current"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

최종 결과

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <body> 
     <sec> 
     <title>The sec 1</title> 
     <p>Text 1</p> 
     </sec> 
    </body> 
    <inline-formula> 
     <math display="inline"> 
     <mi>A</mi> 
     <mn>4.</mn> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"><!--Text node, before dot is removed--> 
     <mn>651</mn> 
     <mi>The next text</mi> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
     <mrow> 
      <mrow> 
       <mi>B</mi> 
      </mrow> 
      <mrow> 
       <mn>4.</mn> 
      </mrow> 
     </mrow> 
     </math> 
    </inline-formula> 
    <inline-formula> 
     <math display="inline"> 
     <mrow> 
      <mrow/> 
      <mrow><!--Text node, before dot is removed--> 
       <mn>651</mn> 
      </mrow> 
     </mrow> 
     <mi>The next text</mi> 
     </math> 
    </inline-formula> 
</root> 

결과 빈 mrow 요소를 포함한다. 이 중요한 경우에, 당신은 다시 그것을 처리 할 방법 빈 요소 명확하지 않다, 두 번째 변화에

<xsl:template match="mrow/mrow[not(mn)]" mode="second"/> 

의 라인을 따라 다른 템플릿을 추가 할 수 있지만 수 있습니다.

+0

제안 주셔서 감사합니다. 이것은 렌더링 팀의 라이브 요구 사항 중 하나입니다. 여기서는 ** FIRST dot **을 기반으로 방정식을 분할해야합니다. 물론 ** MN ** 요소 및 '** 다음 텍스트 * * '는 첫 번째 MN (점이 있음)이 따라 올 수있는 임의의 콘텐츠 또는 임의의 수의 요소 일 수있다. –

관련 문제