2010-06-30 5 views
0

저는 아직 XSLT 초보자이지만 어려운 작업을하고 있습니다.복잡한 XSL 변환

변환 할 필요가있는 비 xml 파일이 있습니다. 파일의 형식은 s는 다음과 같습니다

type1 
type1line1 
type1line2 
type1line3 
type2 
type2line1 
type2line2 
type3 
type3line1 
type3line2 

유형 (type1, type2, ...)는 특정 순서가없는 특정 코드를 사용하여 지정됩니다. 각 유형에는 아래에 복수 line이 있습니다.

그래서이 파일을 변환해야하지만 문제는 각각 type에 대해 기본 행마다 각각 다른 변환을해야한다는 것입니다.

이제 문자열을 한 줄씩 읽고 새로운 형식이 시작되었지만 기본 줄에서 플래그를 사용하여 형식을 나타내는 플래그를 설정하는 방법을 알 수 없습니다. 문제를 해결하는 방법에 대한

<?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" version="2.0"> 
    <xsl:param name="testString" as="xs:string"> 
    type1 
    line1 
    line2 
    type1 
    line1 
    </xsl:param> 
    <xsl:template match="/"> 
    <xsl:call-template name="main"> 
     <xsl:with-param name="testString" select="$testString"/> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="main"> 
    <xsl:param name="testString"/> 
    <xsl:variable name="iniFile" select="$testString"/> 
    <config> 
     <xsl:analyze-string select="$iniFile" regex="\n"> 
     <xsl:non-matching-substring> 
      <item> 
      <xsl:choose> 
       <xsl:when test="starts-with(., 'type1')"> 
    <!-- do a specific transformation-->  
       </xsl:when> 
       <xsl:when test="starts-with(., 'type2')"> 
    <!-- do another transformation-->  
       </xsl:when> 
      </xsl:choose> 
      </item> 
     </xsl:non-matching-substring> 
     </xsl:analyze-string> 
    </config> 
    </xsl:template> 
</xsl:stylesheet> 

어떤 생각을 : 여기

내가 지금 가지고있는 것입니다.

+1

입니다. ** XSLT는 ** XML 파일 **을 변환하기위한 것입니까? ;) –

+1

Niels와 같은 코멘트를 피하기 위해이 질문에 XSLT2로 태그를 답니다. @Niels van der Rest : XSLT2는 분석되지 않은 문서를 조작 할 수 있습니다. –

+0

@Alejandro 저를 바로 잡아 주셔서 감사합니다. 나는 그 사실을 알지 못했습니다. –

답변

0

XSLT 2.1은 문자열과 같은 원자 값의 연속에 대해 for-each-group과 같은 강력한 기능을 사용할 수 있다고 생각하지만 XSLT 2.0을 사용하면 노드의 시퀀스에만 강력한 기능을 사용할 수 있으므로 XSLT 2.0 처리 할 일반 문자열 데이터가있는/group은 요소를 만드는 것입니다. 따라서 데이터를 토큰 화하고 각 토큰을 일부 요소로 랩핑 한 다음 for-each-group 그룹 시작과 함께 '^ type [0-9] + $'와 같은 패턴으로 시작하는 각 그룹을 처리 할 수 ​​있습니다. 당신이 그룹은 그래서 당신이 적용 할 수있는 예를 들어 다음을 식별 한 후 당신은 정말 당신이 데이터에 원하는 걸 말하지 않은 :

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

    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="input" as="xs:string">type1 
type1line1 
type1line2 
type1line3 
type2 
type2line1 
type2line2 
type3 
type3line1 
type3line2</xsl:param> 

    <xsl:template name="main"> 
    <xsl:variable name="lines" as="element(item)*"> 
     <xsl:for-each select="tokenize($input, '\n')"> 
     <item><xsl:value-of select="."/></item> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:for-each-group select="$lines" group-starting-with="item[matches(., '^type[0-9]+$')]"> 
     <xsl:choose> 
     <xsl:when test=". = 'type1'"> 
      <xsl:apply-templates select="current-group() except ." mode="m1"/> 
     </xsl:when> 
     <xsl:when test=". = 'type2'"> 
      <xsl:apply-templates select="current-group() except ." mode="m2"/> 
     </xsl:when> 
     <xsl:when test=". = 'type3'"> 
      <xsl:apply-templates select="current-group() except ." mode="m3"/> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="item" mode="m1"> 
    <foo> 
     <xsl:value-of select="."/> 
    </foo> 
    </xsl:template> 

    <xsl:template match="item" mode="m2"> 
    <bar> 
     <xsl:value-of select="."/> 
    </bar> 
    </xsl:template> 

    <xsl:template match="item" mode="m3"> 
    <baz> 
     <xsl:value-of select="."/> 
    </baz> 
    </xsl:template> 

</xsl:stylesheet> 

색슨 9 (명령 행 옵션을 적용 할 때 - 그것은 : main-xsl : sheet.xsl) 결과는

<foo>type1line1</foo> 
<foo>type1line2</foo> 
<foo>type1line3</foo> 
<bar>type2line1</bar> 
<bar>type2line2</bar> 
<baz>type3line1</baz> 
<baz>type3line2</baz>