XSLT从一系列数据中获得第一行

问题描述:

我看到了一些非常类似的问题,但解决方案似乎不适用于我的案例。XSLT从一系列数据中获得第一行

我有看起来像这样的XML。

<AdLocInfo> 
      <ExternalRunSchedNumber/> 
      <RunSchedule-id>280896</RunSchedule-id> 
      <publication-id>181</publication-id> 
      <publication>SWEB</publication> 
      <publication-placement-id>10</publication-placement-id> 
      <publication-placement>Legals</publication-placement> 
      <publication-position-id>21</publication-position-id> 
      <publication-position>Legal - Notices</publication-position> 
      <import-price>0.00</import-price> 
      <rundates> 
       <date Insertion-id="1530082" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05042017 15:30:00">05062017</date> 
       <date Insertion-id="1530083" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05052017 15:30:00">05072017</date> 
       <date Insertion-id="1530084" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05052017 15:30:00">05082017</date> 
       <date Insertion-id="1530085" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05082017 15:30:00">05092017</date> 
       <date Insertion-id="1530086" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05092017 15:30:00">05102017</date> 
       <date Insertion-id="1530087" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05102017 15:30:00">05112017</date> 
       <date Insertion-id="1530088" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05112017 15:30:00">05122017</date> 
       <date Insertion-id="1530089" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05112017 15:30:00">05132017</date> 
       <date Insertion-id="1530090" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05122017 15:30:00">05142017</date> 
       <date Insertion-id="1530091" InvoicedAlreadyFlag="true" PublishedFlag="true" Deadline="05122017 15:30:00">05152017</date> 

我想拉出系列中的第一个和最后一个日期。

我的XSL是这样的:

<xsl:for-each select="AdBaseInfo"> 
     <ad> 
      <paperId>5344</paperId> 
      <paperItemId> 
       <xsl:value-of select="Ad/AdNumber"/> 
      </paperItemId> 
      <itemDesc> 
       <!--<xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>--> 
       <xsl:value-of select="Ad/ad-content"/> 
       <!--<xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>--> 
      </itemDesc> 
      <startDate> 
       <xsl:for-each select="//date[1]"> 
        <xsl:value-of select="concat(substring(., 5, 4), '-', substring(., 1, 2), '-', substring(., 3, 2))" /> 
       </xsl:for-each> 
      </startDate> 

但是,这导致从每个XML文件中记录的第一道防线。

<ad> 
<paperId>5344</paperId> 
<paperItemId>0000119016-01</paperItemId> 
<itemDesc/> 
<startDate>2017-05-062017-05-242017-06-012017-06-012017-06-082017-05-272017-06-082017-06-082017-06-072017-06-072017-06-082017-06-082017-07-012017-06-082017-06-082017-06-072017-06-082017-06-10</startDate> 
<expDate/> 
<categoryId>S-Main Legal ROP</categoryId> 

任何帮助将不胜感激。

您必须从创建date元素(dates), 的排序列表开始,但不能仅仅进行“普通”复制。

此变量的内容以for-each环路创建与 sort指令内,处理原始date元件。

排序顺序是年月日

循环的每回合增加dates变量date节点, 只有日期(文本节点),但在适当的(目标)格式。

如果出于任何原因您需要更多东西,请复制到新创建的元素 你需要的任何属性。

考虑到上述情况,我选择创建节点的列表,而不仅仅是列表。

然后,如果你想获得最小或最大的日期,它是足够写:

  • <xsl:value-of select="$dates/date[1]"/>
  • <xsl:value-of select="$dates/date[last()]"/>

下面有一个完整的脚本,为工作的样本输入。

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="rundates"> 
    <xsl:copy> 
     <xsl:variable name="dates"> 
     <xsl:for-each select="date"> 
      <xsl:sort select="concat(substring(., 5, 4), 
      '-', substring(., 1, 2), '-', substring(., 3, 2))"/> 
      <date> 
      <xsl:value-of select="concat(substring(., 5, 4), 
       '-', substring(., 1, 2), '-', substring(., 3, 2))" /> 
      </date> 
     </xsl:for-each> 
     </xsl:variable> 
     <minDate> 
     <xsl:value-of select="$dates/date[1]"/> 
     </minDate> 
     <maxDate> 
     <xsl:value-of select="$dates/date[last()]"/> 
     </maxDate> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="AdLocInfo"> 
    <xsl:apply-templates select="rundates"/> 
    </xsl:template> 
</xsl:transform>