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

时间:2017-06-06 22:33:02

标签: xml 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>

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您必须从创建date元素(dates)的排序列表开始, 但不仅仅是&#34;普通&#34;复制。

此变量的内容是在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>