2012-10-01 39 views
7

mô hình dữ liệu của tôi là như sau:Get nhất ngày gần đây trong hồ sơ 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> 

Tôi đã cố gắng sử dụng các câu trả lời đưa ra ở đây: XSLT: Getting the latest date nhưng nó isnt đem lại cho tôi bất kỳ giá trị.

Tôi đang cố gắng để người chơi trẻ nhất vượt qua chức năng bên ngoài.

tôi đang làm điều này trong BizTalk vì vậy tôi phải dính vào XSLT1

Công việc của tôi cho đến nay như sau:

<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> 

Đây là một phần của một mẫu lớn - Tôi có thể không thực sự thay đổi điều này, nhưng giá trị của sưng rễ là "<xsl:variable name="ClubRoot" select="/*[1]"/>" để đảm bảo tôi có thể đọc các nút con của nó.

tôi luôn nhận được

<blahhh>false</blahhh> 
<blahhh/> 

làm giá trị gỡ lỗi của tôi ... vì vậy tôi không chọn giá trị tôi mong đợi

Ai đó có thể làm nổi bật nơi tôi đã đi sai?

Từ dữ liệu ở trên, tôi mong đợi giá trị 14-01-1993 trong biến nhỏ nhất của tôiPlayer. Nhưng nó trống.

Trả lời

6

Vấn đề là XSLT1.0 không thực sự có khái niệm về ngày tháng, vì vậy bạn đang phân loại hiệu quả theo các yếu tố DateOfBirth như thể chúng chỉ là chuỗi bình thường. Nếu bạn có thể chắc chắn những ngày luôn quay theo định dạng DD-MM-YYYY bạn có thể sử dụng chuỗi thao tác để sắp xếp theo năm, tháng và ngày

<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"/> 

Vì vậy, với XSLT sau

<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> 

Khi áp dụng cho XML của bạn, sau đây là sản lượng

14-01-1993 
+2

Bằng việc sử dụng dịch() chức năng, bạn có thể giảm số lượng của xsl: sort hướng dẫn từ 3 đến 1, VÀ đơn giản hóa biểu thức 'xsl: sort/@ select'. –

1

lý do tại sao ngày sắp xếp trong tài liệu tham khảo liên kết của bạn 'làm việc' là bởi vì nó là ở định dạng yyyy-MM-dd, như trái ngược với y định dạng dd-MM-yyyy của chúng tôi. Một thay thế cho đề xuất của Tim C/Sean là sử dụng các hàm C# script (vì bạn đang sử dụng BizTalk) để hoàn nguyên ngày thành một liên kết có thể sắp xếp theo liên kết của bạn - nhưng lưu ý rằng điều này có vẻ không phải là người biểu diễn hàm xslt. Cũng lưu ý rằng bạn có thể cần phải sử dụng msxsl:node-set trên các biến của mình để thông báo cho trình phân tích cú pháp của BizTalk rằng đây là một phân đoạn.

<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> 

Tôi đã lấy một hack tại chức năng và đoán rằng giới hạn tuổi vị thành niên là 21. Các lợi nhuận trên

<blahhh>true</blahhh> 
<blahhh>14-01-1993</blahhh>