2016-12-21 1 views
0

제목, 범주 및 리그가있는 축구 경기의 XML 문서를 고려하십시오.Muenchian 그룹 XSLT 1.0 요소 선택

<?xml version='1.0'?> 
<games> 
    <game> 
     <title>Manchester City - Arsenal</title> 
     <category>Live</category> 
     <league>Premier League</league> 
    </game> 
    <game> 
     <title>Barcelona - Real Madrid</title> 
     <category>Live</category> 
     <league>Primera Division</league> 
    </game> 
    <game> 
     <title>Arsenal - Hull City</title> 
     <category>Recap</category> 
     <league>Premier League</league> 
    </game> 
    <game> 
     <title>Everton - Liverpool</title> 
     <category>Live</category> 
     <league>Premier League</league> 
    </game> 
    <game> 
     <title>Zaragoza - Deportivo</title> 
     <category>Short Recap</category> 
     <league>Primera Division</league> 
    </game> 
</games> 

나는 카테고리에 의해 그룹에이 게임을하려고 해요,하지만 난 단지 <league> 요소는 '프리미어 리그'인에 대한 기록을 유지하려면. 카테고리에는 대응하는 레코드의 수를 나열하는 count 속성도 있어야합니다.

다음과 같은 XSL 파일이 작동하지만 '프리미어 리그'게임이없는 카테고리도 나열된다는 단점이 있습니다. 이상적으로는 카테고리 태그가 없어야합니다.

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

<xsl:key name="prod-cat" match="game" use="category"/> 

    <xsl:template match="/"> 
     <root> 
      <xsl:for-each select="games/game[count(. | key('prod-cat', category)[1]) = 1]"> 

       <category> 

       <xsl:variable name="cat"> 
        <xsl:value-of select="category"/> 
       </xsl:variable> 

       <xsl:variable name="count"> 
        <xsl:value-of select="count(//game[category = $cat][league = 'Premier League'])"/> 
       </xsl:variable> 

       <xsl:attribute name="name"> 
        <xsl:value-of select="category"/> 
       </xsl:attribute> 

       <xsl:attribute name="count"> 
        <xsl:value-of select="$count"/> 
       </xsl:attribute> 

        <xsl:for-each select="key('prod-cat', $cat)[league = 'Premier League']"> 
         <game> 
          <title> 
           <xsl:value-of select="title"/> 
          </title> 
          <cat> 
           <xsl:value-of select="category"/> 
          </cat> 
          <series> 
           <xsl:value-of select="league"/> 
          </series> 
         </game> 
        </xsl:for-each> 
       </category> 
      </xsl:for-each> 
     </root> 
    </xsl:template> 
</xsl:transform> 

결과 : 여기서

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <category name="Live" count="2"> 
     <game> 
     <title>Manchester City - Arsenal</title> 
     <cat>Live</cat> 
     <series>Premier League</series> 
     </game> 
     <game> 
     <title>Everton - Liverpool</title> 
     <cat>Live</cat> 
     <series>Premier League</series> 
     </game> 
    </category> 
    <category name="Recap" count="1"> 
     <game> 
     <title>Arsenal - Hull City</title> 
     <cat>Recap</cat> 
     <series>Premier League</series> 
     </game> 
    </category> 
    <category name="Short Recap" count="0"/> <!--This one needs to go--> 
</root> 

답변

1

나는 키 정의에 조건을 둘 것 :

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:key name="prod-cat" match="game[league = 'Premier League']" use="category"/> 
    <xsl:template match="/"> 
     <root> 
      <xsl:for-each select="games/game[league = 'Premier League'][count(. | key('prod-cat', category)[1]) = 1]"> 
       <category name="{category}" count="{count(key('prod-cat', category))}"> 
        <xsl:for-each select="key('prod-cat', category)"> 
         <game> 
          <title> 
           <xsl:value-of select="title"/> 
          </title> 
          <cat> 
           <xsl:value-of select="category"/> 
          </cat> 
          <series> 
           <xsl:value-of select="league"/> 
          </series> 
         </game> 
        </xsl:for-each> 
       </category> 
      </xsl:for-each> 
     </root> 
    </xsl:template> 
</xsl:transform> 

온라인 http://xsltransform.net/ejivdHq/1에서.

0

는 최적화 된 수정 된 버전이다. 필요한 요소 만 그룹화하고 나머지는 필터링 할 수 있습니다.
편집 : Martin Honnen에게 감사드립니다. 대신 출력에 관련이없는 요소를 없애기 위해 xsl:if을 추가했습니다.

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:key name="prod-cat" match="game" use="category"/> 
    <xsl:template match="/"> 
     <root> 
      <xsl:for-each select="games/game[count(. | key('prod-cat', category)[1]) = 1]"> 
       <xsl:if test="key('prod-cat', category)[league = 'Premier League']"> 
        <category name="{category}" count="{count(key('prod-cat', category)[league = 'Premier League'])}"> 
         <xsl:for-each select="key('prod-cat', category)[league = 'Premier League']"> 
          <game> 
           <title> 
            <xsl:value-of select="title"/> 
           </title> 
           <cat> 
            <xsl:value-of select="category"/> 
           </cat> 
           <series> 
            <xsl:value-of select="league"/> 
           </series> 
          </game> 
         </xsl:for-each> 
        </category> 
       </xsl:if> 
      </xsl:for-each> 
     </root> 
    </xsl:template> 
</xsl:transform> 
+1

'League ='Premier League ''조건을 키 정의의 'match' 속성에 넣어야한다고 생각합니다. 그렇지 않으면 현재 접근 방식에서 요소가 누락 될 수 있습니다. 예를 들어 http://xsltransform.net/ejivdHq를 참조하십시오. 여기서 입력 요소의 순서를 전적으로 변경 한 다음 키에 의해 설정된 그룹의 첫 번째 항목이 다른 리그에 있으므로 코드에서 '라이브'범주를 더 이상 찾지 않습니다. –