2014-02-22 2 views
1

는이 같은 노드를 포함하는 XML 파일이 :RANDOMIZE 노드 주문 XSLT

<values> 
    <item>item 1</item> 
    <item>item 2</item> 
    <item>item 3</item> 
    <item>item 4</item> 
    <item>item 5</item> 
</values> 
내가 XSLT를 사용하여 RANDOMIZE 순서로 목록을 좀하고 싶습니다

:

<values> 
    <item>item 3</item> 
    <item>item 5</item> 
    <item>item 1</item> 
    <item>item 4</item> 
    <item>item 2</item> 
</values> 

을 과 같은 외부 리소스를 사용할 수 없습니다. "xmlns : java ="java.lang.Math " 및 "xmlns : math = "http://exslt.org/math"

의 제한 때문에.

어쩌면이 링크는 도움이 될 수 있습니다 :

http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm

+1

"시드"(예 : 현재 날짜 또는 시간)를 제공하기위한 * 외부 입력이 없으면 ** 임의 의사 랜덤 생성기는 시작할 때마다 동일한 순서의 번호를 생성합니다. 이것이 여기서 무작위 배정의 목적을 충족 시킨다면 아마도 미리 생성 된 난수 목록을 사용할 수있을 것입니다. –

+0

임의의 숫자를 만들어 xslt에 입력 할 수 있습니다. – CodePro

+0

매개 변수로 사용 하시겠습니까? 그게 좋을거야. 자, EXSLT node-set() 함수를 사용할 수 있습니까? –

답변

5

다음 스타일 시트는 임의의 순서로에 출력 트리 에 항목을 기록합니다. 스타일 시트는 런타임에 외부 "초기 시드"번호가 매개 변수로 제공 될 것으로 예상합니다.

참고 : 항목을 처리하지 않고 다시 정렬하기 때문에 항목을 정렬 할 필요가 없으므로 나중에 EXSLT node-set() 함수가 필요하지 않습니다. 디폴트의 ​​초기 시드 (123)가 사용자의 입력에인가

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

<xsl:param name="initial-seed" select="123"/> 

<xsl:template match="/"> 
    <values> 
      <xsl:call-template name="pick-random-item"> 
       <xsl:with-param name="items" select="values/item"/> 
      </xsl:call-template> 
    </values> 
</xsl:template> 

<xsl:template name="pick-random-item"> 
    <xsl:param name="items" /> 
    <xsl:param name="seed" select="$initial-seed"/> 
    <xsl:if test="$items"> 
     <!-- generate a random number using the "linear congruential generator" algorithm --> 
     <xsl:variable name="a" select="1664525"/> 
     <xsl:variable name="c" select="1013904223"/> 
     <xsl:variable name="m" select="4294967296"/> 
     <xsl:variable name="random" select="($a * $seed + $c) mod $m"/> 
     <!-- scale random to integer 1..n --> 
     <xsl:variable name="i" select="floor($random div $m * count($items)) + 1"/> 
     <!-- write out the corresponding item --> 
     <xsl:copy-of select="$items[$i]"/> 
     <!-- recursive call with the remaining items --> 
     <xsl:call-template name="pick-random-item"> 
      <xsl:with-param name="items" select="$items[position()!=$i]"/> 
      <xsl:with-param name="seed" select="$random"/> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

출력은 :

1234 시드 수행
<?xml version="1.0" encoding="utf-8"?> 
<values> 
    <item>item 2</item> 
    <item>item 3</item> 
    <item>item 1</item> 
    <item>item 4</item> 
    <item>item 5</item> 
</values> 

출력은 :

<?xml version="1.0" encoding="utf-8"?> 
<values> 
    <item>item 4</item> 
    <item>item 1</item> 
    <item>item 5</item> 
    <item>item 2</item> 
    <item>item 3</item> 
</values> 
+0

우수한 코드! 고맙습니다! – CodePro