2013-07-19 2 views
1

다음 소스 파일을 XML로 변환하고 클래스 특성을 기반으로 요소를 정렬해야합니다. 변환은 잘 작동하지만 클래스 속성을 기반으로 정렬을 적용 할 수 없기 때문에 모든 HD 노래와 SD 노래가 그룹화됩니다. xsl : perform-sort를 시도했지만 XSLT에서 어디서 어떻게 적용해야할지 모르겠습니다. 여기 소스 파일을 변환하고 단일 XSLT를 사용하여 클래스를 기반으로 요소 정렬

<html> 
<head> 
    <title></title> 
</head> 
<body> 

    <!-- This is my first comment --> 
<ol> 
    <li>3 Song 1</li> 
    <li>4 Song 2</li> 
    <li>5 Song 3</li> 
    <li>7 Song 4</li> 
    <li>8 Song 5</li> 
    <li>10 Song 6</li> 
    <li>14 Song 7</li> 
    <li>16 Song 8</li> 
    <li>18 Song 9</li> 
    <li>19 Song 10</li> 
    <li>26 Song 11</li> 
    <li>29 Song 12</li> 
    <li>31 Song 13</li> 
    <li>34 Song 14</li> 
    <li>37 Song 15</li> 
    <li>39 Song 16</li> 
    <li>41 Song 17</li> 
    <li>44 Song 18</li> 
    </ol> 

</body> 
</html> 

내 XSLT 2.0 : 여기에

내 소스 파일입니다

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xspf="http://xspf.org/ns/0/" 
    xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="2"> 
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
    <!-- It is very important to add the prefix xspf to the xmlns for xspf otherwise the sorting does not work--> 
    <!--This identity transform template allows to copy the whole document and then drop all the parts that we don't want to keep--> 

    <xsl:template match="/"> 

     <xsl:copy> 

      <xsl:apply-templates/> 


       <xsl:variable name="tracks"> 
        <xsl:perform-sort select="trackList/track"> 
         <xsl:sort select="title/@class" data-type="text" /> 

        </xsl:perform-sort> 
       </xsl:variable> 
       <trackList> 
        <xsl:copy-of select="$tracks"/> 
       </trackList> 

     </xsl:copy> 

    </xsl:template> 

    <!-- Drop the content of the head, hr, and h1 elements --> 
    <xsl:template match="head|hr|h1"/> 

    <!--Copy the content of <ol> and its children--> 
    <xsl:template match="ol"> 
     <!-- TrackList is case sensitive and it was not working without the proper--> 
     <trackList> 
      <xsl:apply-templates/> 
     </trackList> 
    </xsl:template> 


    <!--Copy the content of <li> and its content--> 

    <xsl:template name="mylist" match="li"> 

     <!-- Create new elements track and title as its child and grab the current content of li text, then use the second group of string using tokenize() --> 
     <track> 

      <location> 
       <!-- The substring-before functionality allows to grab the first set of characters/word/number before the provided arg$, in this case space ' '--> 
       <xsl:value-of select="concat('http://localhost/auto/v',substring-before(., ' '),'?dlna')" 
       /> 
      </location> 

      <title> 
       <xsl:variable name="cleaned" select="replace(.,'\(HD\)|-DTV',' HD')"/> 
       <!--    Check if track title contains HD create a class for SD or HD for it --> 
       <xsl:choose> 
        <xsl:when test="contains($cleaned, 'HD')"> 
         <xsl:attribute name="class"> 
          <xsl:text>HD</xsl:text> 
         </xsl:attribute> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:attribute name="class"> 
          <xsl:text>SD</xsl:text> 
         </xsl:attribute> 
        </xsl:otherwise> 
       </xsl:choose> 

       <!-- Create a variable to hold the cleaned title for every track --> 

       <!--<xsl:value-of select="replace(.,'(HD)','HD',substring-after(., ' '))" />--> 
       <xsl:value-of select="substring-after($cleaned, ' ')"/> 


      </title> 
      <extension application="http://www.videolan.org/vlc/playlist/0"> 
       <vlc:id> 
        <!-- Count the number of <li> as they represent a single track --> 
        <xsl:number count="li"/> 
        <!--<xsl:value-of select="substring-before(., ' ')"/>--> 
       </vlc:id> 
      </extension> 
     </track> 
    </xsl:template> 

    <!--Copy the content of <body> and its children. This snippet was at the beginning of the document, but then I moved it to the end of the XSLT--> 

    <xsl:template match="body"> 
     <playlist> 
      <title>Playlist</title> 

      <xsl:apply-templates/> 

      <!-- By putting the apply-templates above this snippet it makes it generate after the whole document, which is what I wanted to achieve. --> 
      <!-- For every substring-before create a list of vlc:item as found in the automatically created VLC playlist--> 
      <extension application="http://www.videolan.org/vlc/playlist/0"> 
       <xsl:for-each select="(ol/li/text())"> 
        <!-- This allows to create self-closing attribute tag for vlc:id tid--> 
        <xsl:variable name="vlcname"> 
         <xsl:value-of select="substring-before(., ' ')"/> 
        </xsl:variable> 
        <xsl:element name="vlc:item"> 
         <xsl:attribute name="tid"> 
          <!-- Count the number of <li> as they represent a single track --> 
          <xsl:number count="li" format="0"/> 
         </xsl:attribute> 
        </xsl:element> 
       </xsl:for-each> 
      </extension> 
     </playlist> 
    </xsl:template> 
</xsl:stylesheet> 

그리고 그 결과 XML은 다음과 같이한다 :

<?xml version="1.0" encoding="UTF-8"?> 

<playlist xmlns:xspf="http://xspf.org/ns/0/" 
      xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/"> 
    <title>Playlist</title> 


    <trackList> 
     <track> 
     <location>http://localhost/auto/v34?dlna</location> 
     <title class="HD">Song 14 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>14</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v44?dlna</location> 
     <title class="HD">Song 18 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>18</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v7?dlna</location> 
     <title class="HD">Song 4 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>4</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v19?dlna</location> 
     <title class="HD">Song 10 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>10</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v3?dlna</location> 
     <title class="SD">Song 1</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>1</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v4?dlna</location> 
     <title class="SD">Song 2</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>2</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v5?dlna</location> 
     <title class="SD">Song 3</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>3</vlc:id> 
     </extension> 
     </track>  
     <track> 
     <location>http://localhost/auto/v8?dlna</location> 
     <title class="SD">Song 5</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>5</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v10?dlna</location> 
     <title class="SD">Song 6</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>6</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v14?dlna</location> 
     <title class="SD">Song 7</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>7</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v16?dlna</location> 
     <title class="SD">Song 8</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>8</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v18?dlna</location> 
     <title class="SD">Song 9</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>9</vlc:id> 
     </extension> 
     </track> 

     <track> 
     <location>http://localhost/auto/v26?dlna</location> 
     <title class="SD">Song 11</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>11</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v29?dlna</location> 
     <title class="SD">Song 12</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>12</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v31?dlna</location> 
     <title class="SD">Song 13</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>13</vlc:id> 
     </extension> 
     </track> 

     <track> 
     <location>http://localhost/auto/v37?dlna</location> 
     <title class="SD">Song 15</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>15</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v39?dlna</location> 
     <title class="SD">Song 16</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>16</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v41?dlna</location> 
     <title class="SD">Song 17</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>17</vlc:id> 
     </extension> 
     </track> 

    </trackList> 

    <extension application="http://www.videolan.org/vlc/playlist/0"> 
     <vlc:item tid="1"/> 
     <vlc:item tid="2"/> 
     <vlc:item tid="3"/> 
     <vlc:item tid="4"/> 
     <vlc:item tid="5"/> 
     <vlc:item tid="6"/> 
     <vlc:item tid="7"/> 
     <vlc:item tid="8"/> 
     <vlc:item tid="9"/> 
     <vlc:item tid="10"/> 
     <vlc:item tid="11"/> 
     <vlc:item tid="12"/> 
     <vlc:item tid="13"/> 
     <vlc:item tid="14"/> 
     <vlc:item tid="15"/> 
     <vlc:item tid="16"/> 
     <vlc:item tid="17"/> 
     <vlc:item tid="18"/> 
    </extension> 
</playlist> 

답변

1

을 당신이해야 할 시퀀스상의 xsl:perform-sort. /과 일치하는 템플릿을 제거하고 ol과 일치하는 템플릿을 수정하여 XSLT를 약간 수정했습니다. (그리고 멋진 찾고 출력 xsl:strip-space을 추가했습니다. 귀하의 의견이 중요한 공백이있는 경우 당신은 그것을 제거 할 수 있습니다.)

XML 입력 업데이트

<html> 
    <head> 
     <title></title> 
    </head> 
    <body> 

     <!-- This is my first comment --> 
     <ol> 
      <li>3 Song 1</li> 
      <li>4 Song 2</li> 
      <li>5 Song 3 HD</li> 
      <li>7 Song 4</li> 
      <li>8 Song 5</li> 
      <li>10 Song 6 HD</li> 
      <li>14 Song 7</li> 
      <li>16 Song 8</li> 
      <li>18 Song 9</li> 
      <li>19 Song 10 HD</li> 
      <li>26 Song 11</li> 
      <li>29 Song 12</li> 
      <li>31 Song 13 HD</li> 
      <li>34 Song 14</li> 
      <li>37 Song 15</li> 
      <li>39 Song 16</li> 
      <li>41 Song 17 HD</li> 
      <li>44 Song 18</li> 
     </ol> 

    </body> 
</html> 

(몇 li 일부 HD 추가) XSLT 2.0

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xspf="http://xspf.org/ns/0/" 
    xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="2"> 
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <!-- It is very important to add the prefix xspf to the xmlns for xspf otherwise the sorting does not work--> 
    <!--This identity transform template allows to copy the whole document and then drop all the parts that we don't want to keep--> 

    <!-- Drop the content of the head, hr, and h1 elements --> 
    <xsl:template match="head|hr|h1"/> 

    <!--Copy the content of <ol> and its children--> 
    <xsl:template match="ol"> 
     <!-- TrackList is case sensitive and it was not working without the proper--> 
     <trackList>   
      <xsl:variable name="tracks"> 
       <xsl:apply-templates/> 
      </xsl:variable> 

      <xsl:perform-sort select="$tracks/*"> 
       <xsl:sort select="title/@class"/> 
      </xsl:perform-sort>   
     </trackList> 
    </xsl:template> 


    <!--Copy the content of <li> and its content--> 

    <xsl:template name="mylist" match="li"> 

     <!-- Create new elements track and title as its child and grab the current content of li text, then use the second group of string using tokenize() --> 
     <track> 

      <location> 
       <!-- The substring-before functionality allows to grab the first set of characters/word/number before the provided arg$, in this case space ' '--> 
       <xsl:value-of select="concat('http://localhost/auto/v',substring-before(., ' '),'?dlna')" 
       /> 
      </location> 

      <title> 
       <xsl:variable name="cleaned" select="replace(.,'\(HD\)|-DTV',' HD')"/> 
       <!--    Check if track title contains HD create a class for SD or HD for it --> 
       <xsl:choose> 
        <xsl:when test="contains($cleaned, 'HD')"> 
         <xsl:attribute name="class"> 
          <xsl:text>HD</xsl:text> 
         </xsl:attribute> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:attribute name="class"> 
          <xsl:text>SD</xsl:text> 
         </xsl:attribute> 
        </xsl:otherwise> 
       </xsl:choose> 

       <!-- Create a variable to hold the cleaned title for every track --> 

       <!--<xsl:value-of select="replace(.,'(HD)','HD',substring-after(., ' '))" />--> 
       <xsl:value-of select="substring-after($cleaned, ' ')"/> 


      </title> 
      <extension application="http://www.videolan.org/vlc/playlist/0"> 
       <vlc:id> 
        <!-- Count the number of <li> as they represent a single track --> 
        <xsl:number count="li"/> 
        <!--<xsl:value-of select="substring-before(., ' ')"/>--> 
       </vlc:id> 
      </extension> 
     </track> 
    </xsl:template> 

    <!--Copy the content of <body> and its children. This snippet was at the beginning of the document, but then I moved it to the end of the XSLT--> 

    <xsl:template match="body"> 
     <playlist> 
      <title>Playlist</title> 

      <xsl:apply-templates/> 

      <!-- By putting the apply-templates above this snippet it makes it generate after the whole document, which is what I wanted to achieve. --> 
      <!-- For every substring-before create a list of vlc:item as found in the automatically created VLC playlist--> 
      <extension application="http://www.videolan.org/vlc/playlist/0"> 
       <xsl:for-each select="(ol/li/text())"> 
        <!-- This allows to create self-closing attribute tag for vlc:id tid--> 
        <xsl:variable name="vlcname"> 
         <xsl:value-of select="substring-before(., ' ')"/> 
        </xsl:variable> 
        <xsl:element name="vlc:item"> 
         <xsl:attribute name="tid"> 
          <!-- Count the number of <li> as they represent a single track --> 
          <xsl:number count="li" format="0"/> 
         </xsl:attribute> 
        </xsl:element> 
       </xsl:for-each> 
      </extension> 
     </playlist> 
    </xsl:template> 
</xsl:stylesheet> 

출력

<playlist xmlns:xspf="http://xspf.org/ns/0/" 
      xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/"> 
    <title>Playlist</title> 
    <trackList> 
     <track> 
     <location>http://localhost/auto/v5?dlna</location> 
     <title class="HD">Song 3 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>3</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v10?dlna</location> 
     <title class="HD">Song 6 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>6</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v19?dlna</location> 
     <title class="HD">Song 10 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>10</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v31?dlna</location> 
     <title class="HD">Song 13 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>13</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v41?dlna</location> 
     <title class="HD">Song 17 HD</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>17</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v3?dlna</location> 
     <title class="SD">Song 1</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>1</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v4?dlna</location> 
     <title class="SD">Song 2</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>2</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v7?dlna</location> 
     <title class="SD">Song 4</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>4</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v8?dlna</location> 
     <title class="SD">Song 5</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>5</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v14?dlna</location> 
     <title class="SD">Song 7</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>7</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v16?dlna</location> 
     <title class="SD">Song 8</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>8</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v18?dlna</location> 
     <title class="SD">Song 9</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>9</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v26?dlna</location> 
     <title class="SD">Song 11</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>11</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v29?dlna</location> 
     <title class="SD">Song 12</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>12</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v34?dlna</location> 
     <title class="SD">Song 14</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>14</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v37?dlna</location> 
     <title class="SD">Song 15</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>15</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v39?dlna</location> 
     <title class="SD">Song 16</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>16</vlc:id> 
     </extension> 
     </track> 
     <track> 
     <location>http://localhost/auto/v44?dlna</location> 
     <title class="SD">Song 18</title> 
     <extension application="http://www.videolan.org/vlc/playlist/0"> 
      <vlc:id>18</vlc:id> 
     </extension> 
     </track> 
    </trackList> 
    <extension application="http://www.videolan.org/vlc/playlist/0"> 
     <vlc:item tid="1"/> 
     <vlc:item tid="2"/> 
     <vlc:item tid="3"/> 
     <vlc:item tid="4"/> 
     <vlc:item tid="5"/> 
     <vlc:item tid="6"/> 
     <vlc:item tid="7"/> 
     <vlc:item tid="8"/> 
     <vlc:item tid="9"/> 
     <vlc:item tid="10"/> 
     <vlc:item tid="11"/> 
     <vlc:item tid="12"/> 
     <vlc:item tid="13"/> 
     <vlc:item tid="14"/> 
     <vlc:item tid="15"/> 
     <vlc:item tid="16"/> 
     <vlc:item tid="17"/> 
     <vlc:item tid="18"/> 
    </extension> 
</playlist> 
+0

Daniel에게 감사드립니다. – ManUO

+0

Hello Daniel, 을 지금 상태로 유지하는 대신 하나로 시작하도록 재설정하려면 어떻게해야합니까? 나는 몇 가지 해결책을 시도했지만 효과가있다. vlc : id 요소가 생성 된 후에 클래스 별 순서가 실행되는 것 같습니다. 기본적으로 첫 번째 트랙에는 항상 vlc : id 값 1이 있어야하며 번호 매기기는 그 시점부터 올라야합니다. – ManUO

관련 문제