2016-03-21 7 views
0

У меня есть XML, как это, и вы хотите:XSL узел сортировать по дате, возвращать первый узел

-sort на employment_information/датой_начала, восходящие.

-подтвердите узлы CompoundEmployee только с первым отсортированным узлом job_information.

Примечание: формат даты гггг-мм-дд

<?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> 
+0

Дефисы в датах всегда в одном месте. Вы можете просто отсортировать всю «дату начала» и игнорировать дефисы, поскольку они не повлияют на порядок сортировки. –

+0

Почему этот тегированный XSLT 2.0, в то время как ваша таблица стилей XSLT 1.0? –

+0

Решение XSLT 2.0 также приветствуется, так как сортировка проще. Думал, что я просто добавил тег, но удалил его. – user2215655

ответ

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

Спасибо, это трюк! – user2215655

Смежные вопросы