2010-08-23 4 views
1

XSLT로 텍스트를 출력하고 있습니다. 각 섹션의 줄 수를 계산하여 출력 파일에 써야합니다. 어떻게 할 수 있니?xslt를 사용하여 출력 행을 계산하는 방법은 무엇입니까?

내 출력은 다음과 같다 :

 
HDR+aaa:bbb' 
AAA+789String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+112211' 
DDD+121122' 
XXX+number_of_records+789' 
AAA+1234567890+String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+1212:2121' 
BBB+123+String' 
BBB+122+String' 
CCC+String' 
XXX+number_of_records+1234567890' 

number_of_records 두 라인을 포함 XXX하는 AAA에서 라인의 수를 포함해야합니다. 첫 번째 섹션에서 줄 수는 6이어야하며 두 번째 메시지에서는 8이어야합니다. 각 섹션의 첫 번째 줄과 마지막 줄은 동일한 고유 한 ID 번호를 공유합니다.

XSLT 내에 많은 처리가 있기 때문에 줄 수는 소스에서 계산할 수 없습니다. 그냥 재미를 위해

+1

입력이나 샘플이 없으면 아무도 여기에서 많은 도움을 줄 수 없습니다. XSLT 1 또는 2를 사용하고 있습니까? 어떤 프로세서를 사용하고 있습니까? –

+0

XSLT를 게시하면 필요한 항목을 식별하는 데 필요합니다. –

답변

1

, 당신은 당신의 입력 샘플과 스타일의 건물을 게시 할 때까지 텍스트 출력이 스타일이 입력으로

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="result" name="result"> 
     <xsl:param name="pString" select="."/> 
     <xsl:variable name="vAfter" select="substring-after($pString, 'AAA+')"/> 
     <xsl:choose> 
      <xsl:when test="$vAfter!=''"> 
       <xsl:variable name="vId" 
         select="substring-before($vAfter, '+')"/> 
       <xsl:variable name="vEnd" 
        select='concat("XXX+number_of_records+",$vId,"&apos;&#xA;")'/> 
       <xsl:variable name="vInto" 
         select="substring-before($vAfter,$vEnd)"/> 
       <xsl:value-of 
         select='concat(substring-before($pString,"AAA+"), 
          "AAA+", 
          $vInto, 
          "XXX+", 
          string-length(translate($vInto, 
                translate($vInto, 
                   "&#xA;", 
                   ""), 
                "")) + 1, 
          "+",$vId,"&apos;&#xA;")'/> 
       <xsl:call-template name="result"> 
        <xsl:with-param name="pString" 
         select="substring-after($vAfter,$vEnd)"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$pString"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

:

<result> 
HDR+aaa:bbb' 
AAA+789String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+112211' 
DDD+121122' 
XXX+number_of_records+789' 
AAA+1234567890+String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+1212:2121' 
BBB+123+String' 
BBB+122+String' 
CCC+String' 
XXX+number_of_records+1234567890' 
</result> 

출력 :

HDR+aaa:bbb' 
AAA+789String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+112211' 
DDD+121122' 
XXX+6+789' 
AAA+1234567890+String1:String2' 
BBB+123+String' 
CCC+321:1212' 
DDD+1212:2121' 
BBB+123+String' 
BBB+122+String' 
CCC+String' 
XXX+8+1234567890' 
2

개념적으로 간단한 방법은 두 번째 단계 프로세스를 사용하는 것입니다. 초기 변환 결과 (게시 한 내용)를 가져 와서 줄에 구문 분석하는 템플릿 (또는 @ Alejandro 's와 같은 스타일 시트)을 통해 실행하고 AAA ...으로 시작하여 XXX으로 끝나는 줄을 그룹화합니다. tokenize(), xsl:analyze-stringxsl:for-each-group을 사용하여 매우 명확하고 실용적인 자습서를 보려면 Up-conversion using XSLT 2.0을 참조하십시오. 그런 다음 각 그룹의 행을 계산하고 각 행을 다시 출력하고 행 수를 XXX 레코드에 연결하십시오.

하지만 초기 출력을 파싱 할 때 비효율적이며 다소 오류가 발생하기 쉽습니다. 왜 스타일 시트가 이미 내부적으로 가지고있는 정보의 직렬화를 파싱합니까? 당신은

<hdr> 
    <section id="789"> 
    <!-- It sounds like AAA's ID actually applies to the section? --> 
    <AAA String1="..." String2="..."/> 
    <BBB .../> 
    <!-- no need to include XXX at this stage AFAICT --> 
    </section> 
    <section id="1234567890"> 
    ... 
    </section> 
</hdr> 
다음

제 2 단계 템플릿 (또는 별도의 스타일 시트)과 같은 초기 XML로 출력, 뭔가를 변경하여 비 효율성을 피할 수 입력으로이 XML을 매우 쉽게 위했던 것처럼 직렬화 수 , 줄을 세면서 계산합니다. XSLT 1.0에서는 별도의 스타일 시트를 사용하여 출력 XML을 처리하거나 extension function node-set()을 사용해야합니다. (하지만 별도의 스타일 시트 프로세서를 사용하더라도 SAX를 사용하여 두 스타일 시트 프로세서를 함께 파이프 라인 할 수 있다면 중간 XML을 다시 파싱하는 비용을 피할 수 있습니다.) XSLT 2.0에서는 한 템플릿의 XML 출력을 다른 템플릿, 제한없이.

0

내 솔루션 : 나는 전화 할 때마다 number_of_records를 1 씩 증가시키는 확장 함수를 만들었습니다. xsl : comment를 사용하여 실제로 출력 할 때까지 출력을 억제합니다. 각 XXX + 라인 다음에 number_of_records를 재설정했습니다.

두 단계로 수행하면 너무 많은 번거 로움을 초래할 수 있습니다.

관련 문제