XSL按日期排序节点,返回第一个节点

时间:2016-03-21 21:09:41

标签: xslt

我有这样的XML,并希望:

-sort on employment_information / start_date,升序。

- 仅使用第一个已排序的employment_information节点返回CompoundEmployee节点。

注意:日期格式为yyyy-mm-dd

<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
 <CompoundEmployee>
  <person>
   <person_id>913</person_id>
   <person_id_external>uat_dddd</person_id_external>
   <employment_information>
    <custom_string1>aaaa</custom_string1>
    <start_date>2015-01-01</start_date>
    <end_date>2015-12-31</end_date>
    <user_id>uat_aaaa</user_id>
   </employment_information>
   <employment_information>
    <custom_string1>bbbb</custom_string1>
    <start_date>2016-01-01</start_date>
    <end_date>2016-12-31</end_date>
    <user_id>uat_bbbb</user_id>
   </employment_information>
  </person>
</CompoundEmployee>
<CompoundEmployee>
 <person>
   <person_id>914</person_id>
   <person_id_external>uat_dddd</person_id_external>
   <employment_information>
    <custom_string1>cccc</custom_string1>
    <start_date>2016-02-01</start_date>
    <end_date>2016-12-31</end_date>
    <user_id>uat_cccc</user_id>
   </employment_information>
   <employment_information>
   <custom_string1>dddd</custom_string1>
    <start_date>2015-02-01</start_date>
    <end_date>2015-12-31</end_date>
    <user_id>uat_dddd</user_id>
   </employment_information>
  </person>
 </CompoundEmployee>
</queryCompoundEmployeeResponse>

我已经找到了排序,但是如何选择第一个节点?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="queryCompoundEmployeeResponse/CompoundEmployee/person">
 <xsl:copy>
  <xsl:apply-templates select="employment_information">
    <!--  concat year, month, day -->
    <xsl:sort select="concat(
              substring(start_date, 1, 4),
              substring(start_date, 6, 2),
              substring(start_date, 9, 2) 
              )" order="ascending"/>
  </xsl:apply-templates>
 </xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
 <xsl:copy>
  <xsl:apply-templates select="@* | node()"/>
 </xsl:copy>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

试试这个XSLT 1.0解决方案:

<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:strip-space elements="*"/>

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

<xsl:template match="person">
    <xsl:copy>
        <xsl:apply-templates select="person_id | person_id_external"/>
        <xsl:for-each select="employment_information">
            <xsl:sort select="start_date" data-type="text" order="ascending"/>
            <xsl:if test="position()=1">
                <xsl:copy-of select="."/>
            </xsl:if>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
   <CompoundEmployee>
      <person>
         <person_id>913</person_id>
         <person_id_external>uat_dddd</person_id_external>
         <employment_information>
            <custom_string1>aaaa</custom_string1>
            <start_date>2015-01-01</start_date>
            <end_date>2015-12-31</end_date>
            <user_id>uat_aaaa</user_id>
         </employment_information>
      </person>
   </CompoundEmployee>
   <CompoundEmployee>
      <person>
         <person_id>914</person_id>
         <person_id_external>uat_dddd</person_id_external>
         <employment_information>
            <custom_string1>dddd</custom_string1>
            <start_date>2015-02-01</start_date>
            <end_date>2015-12-31</end_date>
            <user_id>uat_dddd</user_id>
         </employment_information>
      </person>
   </CompoundEmployee>
</queryCompoundEmployeeResponse>