2016-07-13 2 views
0

코드 줄을 블록으로 그룹화하려고 할 때 부모님의 텍스트가 손실되어 그 이유를 모르겠습니다.XSLT - 그룹화 및 부모 텍스트 손실

XML

<body> 
    <ul> 
    <li>before 
     <filepath>one test</filepath> now some code: 
     <codeblock>1</codeblock> 
     <codeblock>2</codeblock> 
     after text</li> 
    </ul> 
    <section> 
    <title>Test2</title> 
    <p>qqqq</p> 
    <codeblock>1</codeblock> 
    <codeblock>2</codeblock> 
    <codeblock>3</codeblock> 
    </section> 
</body> 

XSLT

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

<xsl:template match="@*|node()"> 
    <xsl:choose> 
     <xsl:when test="./codeblock[1] or ./msgblock[1]"> 
      <xsl:call-template name="merge-codeblock"> 
       <xsl:with-param name="container" select="."/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy> 
       <xsl:apply-templates select="@* | node()" /> 
      </xsl:copy> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="merge-codeblock"> 
    <xsl:param name="container"/>  
      <xsl:copy> 
       <xsl:for-each-group select="*" group-adjacent="boolean(self::codeblock or self::msgblock)"> 
        <xsl:choose> 
         <xsl:when test="current-grouping-key() and count(current-group()) gt 1"> 
          <xsl:element name="{name()}"> 
           <xsl:variable name="name" select="current-group()/node()" /> 
           <xsl:for-each select="current-group()/node()"> 
            <xsl:variable name="namee" select="current()" /> 
            <xsl:apply-templates select="current()" /> 
            <xsl:text>&#10;</xsl:text> 
           </xsl:for-each> 
          </xsl:element> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:apply-templates select="current-group()" /> 
         </xsl:otherwise> 
        </xsl:choose> 
       </xsl:for-each-group> 
      </xsl:copy>   
</xsl:template> 

</xsl:stylesheet> 

나는이 문제를 해결하지만 내 codeblock 요소가없는 내 그룹 선택에 |text()를 추가하려고했습니다

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd"><!--<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd">--><body> 
    <ul> 
     <li><!-- not ok! I lost my li/text() --> 
     <filepath>one test</filepath> 
     <codeblock>1 
2 
</codeblock> 
     </li> 
    </ul> 
    <section> 
     <title>Test</title> 
     <p>fddsfsd</p> 
     <codeblock>fdsfds</codeblock> 
    </section> 
    <section> 
     <title>Test2</title> 
     <p>qqqq</p> 
     <codeblock>1 
2 
3 
</codeblock> 
    </section> 
</body> 

현재 결과 더 이상 병합되었습니다.

내가 뭘 잘못하고 있니?

편집 : 마틴의 대답은 LI 문제를 해결하지만 불행하게도 지금 추가 내 코드 블록 라인 전에 공간과 첫 번째 코드 블록 후에 캐리지 리턴이 있습니다

<codeblock> 
     1 
     2 
     3 
</codeblock> 

대신 :

<codeblock>1 
2 
3</codeblock> 

어떻게 제거 할 수 있습니까? 아직 current-group()의 공백을 제거하지 않았습니다.

<codeblock> 

1 


2 


3 

    </codeblock> 

을하지만 문제는 이상한 공백으로 남아 :

하기 권장 편집이 날 수 있습니다. current-group()에는 빈 공백에 캐리지 리턴이있는 " ", <codeblock>, " ", <codeblock>, " ", <codeblock>, " "이 포함되어 있습니다.

+0

에 간단하게 할 수 있습니까? 그리고 codeblock 요소 안에는 평범한 텍스트 만있을 수 있습니까? 후자의 경우 가장 쉬운 방법은' group() "/>'. –

+0

나는 당신의 아이디어를 시도했지만 여전히 실패합니다. 다른 아이디어가있을 경우에 대비하여 몇 가지 세부 사항을 게시했습니다 :). – Flag

+0

답변 편집을 참조하십시오. –

답변

1

내가

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

    <xsl:template match="*[codeblock | msgblock]"> 
     <xsl:copy> 
      <xsl:for-each-group select="node()" 
       group-adjacent="boolean(self::text()[not(normalize-space())] | self::codeblock | self::msgblock)"> 
       <xsl:choose> 
        <xsl:when test="current-grouping-key() and current-group()[self::*]"> 
         <xsl:element name="{name(current-group()[self::*[1]][1])}"> 
          <xsl:apply-templates select="current-group()"/> 
         </xsl:element> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:apply-templates select="current-group()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="codeblock | msgblock"> 
     <xsl:apply-templates/> 
    </xsl:template> 
</xsl:stylesheet> 

그룹을 생각하고 텍스트를 유지, 당신은 내가 정확히 당신이 원하는 결과를 확실하지 않다으로 그룹화 된 내용을 출력하는 부분을 적용해야 할 수도 있습니다. 공백 문제에 관해서는

, 당신은 단순히 그 codeblockmsgblock 요소에 일반 텍스트가 가정 당신은 당신이 어떤 결과를 원하는가

   <xsl:choose> 
        <xsl:when test="current-grouping-key() and current-group()[self::*]"> 
         <xsl:element name="{name(current-group()[self::*[1]][1])}"> 
          <xsl:apply-templates select="current-group()"/> 
         </xsl:element> 
        </xsl:when> 

   <xsl:choose> 
        <xsl:when test="current-grouping-key() and current-group()[self::*]"> 
         <xsl:element name="{name(current-group()[self::*[1]][1])}"> 
          <xsl:value-of select="current-group()[self::*]" separator="&#10;"/> 
         </xsl:element> 
        </xsl:when> 
+0

다시 한번, 아주 좋은 접근법. 그것은 내 첫 번째 테스트에 따라 위대한 일을하고있는 것 같습니다. 고마워요! – Flag

+0

나는 내가 알아 차린 문제점을 보여주기 위해 질문을 업데이트했으며, 지금 당장은 많은 성공을 거두지 않고 해결하려고 노력하고있다. 어떤 도움을 주시면 감사하겠습니다. – Flag