2012-10-01 20 views
7

私のデータモデルは次のとおりです。私はここに与えられた答えは使用してみました次のようにXMLレコードで最新の日付を取得します

<Club> 
<Captain> 
<Name></Name> 
<DateOfBirth>15-01-1985</DateOfBirth> 
</Captain> 
<PlayingStaff> 
<Player> 
<DateOfBirth>14-01-1993</DateOfBirth> 
</Player> 
<Player> 
<DateOfBirth>07-12-1975</DateOfBirth> 
</Player> 
<Player> 
<DateOfBirth>11-11-1991</DateOfBirth> 
</Player> 
</PlayingStaff> 
</Club> 

XSLT: Getting the latest dateをしかし、それは私に任意の値を与えてイマイチ。

私は一番若いプレーヤーに外部機能を渡そうとしています。次のように

私は私がこれまでXSLT1

に私の仕事を固執する必要がありのBizTalkでこれをやっているのです:

<xsl:variable name="youngestPlayer"> 
      <xsl:for-each select="$ClubRoot/*[local-name()='PlayingStaff']/*[local-name()='Player']"> 
       <xsl:sort select="./*[local-name()='DateOfBirth']" order="descending"/> 
       <xsl:if test="position() = 1"> 
        <xsl:value-of select="DateOfBirth"/> 
       </xsl:if> 
      </xsl:for-each> 
     </xsl:variable> 
     <xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="externalfunctionreturningboolean"> 
      <xsl:element name="blahhh"><xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/></xsl:element> 
      <xsl:element name="blahhh"><xsl:value-of select="$youngestPlayer"/></xsl:element> 

これは大テンプレートの一部である - 私は本当にすることができますこれを変更するが、根こぶ病の値は、「私はその子ノードを読み取ることができます確保するための<xsl:variable name="ClubRoot" select="/*[1]"/>"です。

私はいつも

<blahhh>false</blahhh> 
<blahhh/> 
01を取得しています

私のデバッグ値として...私は期待した値を拾いません

誰かが間違っていた場所を強調表示できますか?

上記のデータから、私はyoungestPlayer変数に14-01-1993という値があると思います。しかし、その空白。

答えて

6

問題は、XSLT1.0は実際に日付の概念を持たないため、DateOfBirth要素で効果的に並べ替えているように見えます。あなたは日付が常に形式DD-MM-YYYYに来ることを確認することができます場合は、次のXSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/Club"> 
     <xsl:for-each select="PlayingStaff/Player"> 
     <xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/> 
     <xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/> 
     <xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/> 

     <xsl:if test="position() = 1"> 
      <xsl:value-of select="DateOfBirth"/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
与えられた、だから、月、日

<xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/> 
<xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/> 
<xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/> 

、年によってソートする文字列操作を使用することができます

あなたのXMLに適用すると、次はそれがyyyy-MM-dd形式であったため、Yとは対照的に、あなたのリンクを参照してソート日付が「働いていた」理由は、出力した

14-01-1993 
+2

であることを推測してきた、あなたは、XSLの数を減らすことができます。ソート3から1までの命令、そして 'xsl:sort/@ select expression'を単純化します。 –

1

です我々のdd-MM-yyyyフォーマット。

Tim C/Seanの提案では、BizTalkを使用しているため、C#スクリプト関数を使用して、リンクごとに日付をソート可能なものに戻すことができますが、これはネイティブと同じようにはなりませんxslt関数。変数にmsxsl:node-setを使用して、これがフラグメントであることをBizTalkのパーサに伝える必要があることにも注意してください。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       exclude-result-prefixes="userCSharp msxsl" 
       > 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:variable name="ClubRoot" select="/*[1]"/> 
     <xsl:variable name="orderedPlayers"> 
      <xsl:for-each select="msxsl:node-set($ClubRoot)/*[local-name()='PlayingStaff']/*[local-name()='Player']"> 
       <xsl:sort select="userCSharp:makeSortableDate(string(*[local-name()='DateOfBirth']), 'dd-MM-yyyy')" order="descending"/> 
       <xsl:copy-of select="node() | @*"/> 
      </xsl:for-each> 
     </xsl:variable> 

     <xsl:variable name="youngestPlayerDOB"> 
      <xsl:value-of select="msxsl:node-set($orderedPlayers)[1]/DateOfBirth/text()" /> 
     </xsl:variable> 

     <xsl:element name="blahhh"> 
      <xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="userCSharp:externalfunctionreturningboolean($youngestPlayerDOB)" /> 
      <xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/> 
     </xsl:element> 
     <xsl:element name="blahhh"> 
      <xsl:value-of select="$youngestPlayerDOB"/> 
     </xsl:element> 
    </xsl:template> 

    <msxsl:script language="C#" implements-prefix="userCSharp"> 
     <![CDATA[ 
     public System.String makeSortableDate(System.String yourDate, string format) 
     { 
      return (System.DateTime.ParseExact(yourDate, format, System.Globalization.CultureInfo.InvariantCulture).ToString("yyyy-MM-dd")); 
     } 

     public bool externalfunctionreturningboolean(System.String dobString) 
     { 
      System.DateTime someDate; 
      if (System.DateTime.TryParse(dobString, out someDate)) 
      { 
       // NB : Doesn't work out leap years correctly! 
       if ((System.DateTime.Now - someDate).Days < 21 * 365.25) 
       { 
        return true; 
       } 
      } 
      return false; 
     } 
    ]]> 
    </msxsl:script> 

</xsl:stylesheet> 

私は機能でハックを取られ、未成年者の制限が翻訳()関数を使用して21以上のリターン

<blahhh>true</blahhh> 
<blahhh>14-01-1993</blahhh> 
関連する問題