2011-10-17 4 views
2

특정 요소에 사용 된 문자열에 대한 순서를 정의하고 싶습니다. 예를 들어, < 클래스 > 수석 </클래스 > < 클래스 > 주니어 </클래스 > < 클래스 > 학년 </클래스 > < 클래스 > 신입생 < 클래스는 > 클래스에 합리적인 순서를 설명한다.XSLT의 함수를 사용하여 사용자 정의 데이터 정렬을 정의 할 수 있습니까?

< xsl : sort select = 'class'> 위의 순서에 따라 정렬하는 방법이 있습니까?

미리 감사드립니다. 당신이 당신의 XSLT에서 무엇을 할 수 있는지

+0

XSLT 1.0 또는 2.0을 사용하고 있습니까? 색슨은 당신을위한 선택입니까? – LarsH

+0

나는 Saxon을 사용하고 어떤 버전이라도 사용할 수있다. 일반적으로 나는 3을 사용한다. –

답변

4

Saxon의 맞춤 데이터 정렬 확장 프로그램을 살펴 보셨습니까? 예를 들어

,

<xsl:variable name="rules" select="'&lt; Freshman &lt; Sophomore 
            &lt; Junior &lt; Senior'" /> 

이 그 이름의 자바 클래스에서 RuleBasedCollator 형식을 사용합니다.

는 (팀 C의 유용한 예를 입력 XML 및 스타일 시트에 편승) 당신의 종류에이 기능을 사용하려면

<xsl:apply-templates select="object"> 
    <xsl:sort select="@class" 
     collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/> 
</xsl:apply-templates> 

이 팀 C의 솔루션과 같은 결과를 얻을 수 있습니다. (Saxon PE 9.3.0.5를 사용하여 테스트되었습니다.)

이것은 xsl : function이 아니지만 배열보다 약간의 유연성을 제공하며 아마도 더 간결 할 것입니다. AFAICT에는 XSLT 사용자 정의 함수를 사용하여 사용자 지정 데이터 정렬을 만들 수있는 방법이 없습니다. xsl:function을 원하는 이유를 밝히지 않았기 때문에 어떤 대안이 사용자의 요구를 충족 시킬지 추측하기가 어렵습니다.

완벽한 xsl : 기능과 같은 유연성을 얻으려면 Java에서 고유 한 데이터 정렬기를 정의 할 수 있습니다. java.util.Comparator 인터페이스를 구현하고 class 속성에서 비교자를 지정하면 http://www.saxonica.com/documentation/extensibility/collation.xml을 참조하십시오.

+1

나는 함수를 사용하는 것이 유일한 방법이라고 생각했지만, 이것은 나에게 같은 목적을 제공한다. 레벨을 낮추고 자바를 사용하지 않아도된다. 감사. –

+2

이것은 정말 좋은 대답이었습니다. 다른 모든 옵션보다 훨씬 쉽습니다. –

5

그 다음이 '배열'당신은 XSLT 문서 자체를 참조하는 또 다른 변수를 정의 할 수 있습니다에 액세스 할 수 있도록

<xsl:variable name="inline-array"> 
    <class sort="1">Senior</class> 
    <class sort="2">Junior</class> 
    <class sort="3">Sophomore</class> 
    <class sort="4">Freshman</class> 
</xsl:variable> 

처럼, 사용자 정의 순서를 나타내는 변수를 정의 할 수 있습니다 :

당신이 정렬 될 때
<xsl:variable name="array" 
    select="document('')/*/xsl:variable[@name='inline-array']/*" /> 

이 이제 지정된 클래스 이름에 대한 종류 속성을 조회 할 수 있습니다 (현재는() 현재의 노드를 나타냅니다 분류되는)

다음 샘플 XML이를 적용하면 예를 들어
<xsl:sort select="$array[. = current()/@class]/@sort" /> 

, 여기에 ... 전체 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:variable name="inline-array"> 
     <class sort="1">Senior</class> 
     <class sort="2">Junior</class> 
     <class sort="3">Sophomore</class> 
     <class sort="4">Freshman</class> 
    </xsl:variable> 

    <xsl:variable name="array" 
     select="document('')/*/xsl:variable[@name='inline-array']/*"/> 

    <xsl:template match="/objects"> 
     <xsl:copy> 
     <xsl:apply-templates select="object"> 
      <xsl:sort select="$array[. = current()/@class]/@sort" /> 
     </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

입니다

<objects> 
    <object id="2" name="Junior Jo" class="Junior" /> 
    <object id="1" name="Senior Sue" class="Senior" /> 
    <object id="4" name="Freshman Frank" class="Freshman" /> 
    <object id="3" name="Sophie Sophomore" class="Sophomore" /> 
</objects> 

<objects> 
    <object id="1" name="Senior Sue" class="Senior"></object> 
    <object id="2" name="Junior Jo" class="Junior"></object> 
    <object id="3" name="Sophie Sophomore" class="Sophomore"></object> 
    <object id="4" name="Freshman Frank" class="Freshman"></object> 
</objects> 

을 반환 다음
+0

깔끔한 해결책이지만, 더 간단한 것을 기대하고 있었다. 두 클래스 값 (예 : senior 및 junior)을 비교하고 gt, lt 또는 eg를 나타내는 값을 반환하는 xsl : 함수를 정의 할 수 있기를 희망했습니다. –