'环路'通过多个XML元素(同名)来使用XSL 1.0检索最大的集合节点值

时间:2015-10-23 10:15:37

标签: xml xslt xslt-1.0

我正在制作一个简单的HTML网页,使用书店示例,并通过 XML 数据和 XSLT的组合输出我的网页内容( 1.0),但我最近遇到了一个问题,我想从StackOverflow社区收到一些反馈和建议。

背景

在我的书店示例中,我有一系列名为<book></book>的主要元素,其中包含有关<title></title><author></author>等出版物的重要详细信息。

现在,在每个<book></book>元素中,我还有一个名为<promotions></promotions>的重要元素,它包含单个ID号(<promotionNum></promotionNum>),作为链接到相应的主键另一个元素中的节点更详细地处理促销。

XML结构:

<bookstore>
  <book>
    <title>Harry Potter and the Philosopher's Stone</title>
    <author>J K. Rowling</author>
    <year>1997</year>
    <price>3.99</price>
    <publisher>Bloomsbury (UK)</publisher>
    <synopsis>
         Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel.

         The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry.

         With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.
   </synopsis>
   <promotions>
    <promotionNum>1</promotionNum>
    <promotionNum>2</promotionNum>
    <promotionNum>3</promotionNum>
    <promotionNum>4</promotionNum>
   </promotions>
 </book>
 <book>
    <title>The Girl with the Dragon Tattoo</title>
    <author>Stieg Larsson</author>
    <year>2005</year>
    <price>5.99</price>
    <publisher>Norstedts Förlag (SWE)</publisher>
    <synopsis>
         In Stockholm, Sweden, journalist Mikael Blomkvist, co-owner of Millennium magazine, has lost a libel case brought against him by businessman Hans-Erik Wennerström. Lisbeth Salander, a brilliant but troubled investigator and hacker, compiles an extensive background check on Blomkvist for business magnate Henrik Vanger, who has a special task for him. 

         In exchange for the promise of damning information about Wennerström, Blomkvist agrees to investigate the disappearance and assumed murder of Henrik's grandniece, Harriet, 40 years ago. 

         After moving to the Vanger family's compound, Blomkvist uncovers a notebook containing a list of names and numbers that no one has been able to decipher.
    </synopsis>
    <promotions>
      <promotionNum>5</promotionNum>
      <promotionNum>6</promotionNum>
      <promotionNum>3</promotionNum>
      <promotionNum>2</promotionNum>
   </promotions>
  </book>
  <promotion>
    <promotionID>1</promotionID>
    <percentageOff>10</percentageOff>
    <promotionalMerchandise>No</promotionalMerchandise>
    <promotionStartDate>2015-10-14T00:00:00</promotionStartDate>
    <promotionEndDate>2015-10-19T00:00:00</promotionEndDate>
  </promotion>
  <promotion>
    <promotionID>2</promotionID>
    <percentageOff>15</percentageOff>
    <promotionalMerchandise>No</promotionalMerchandise>
    <promotionStartDate>2015-10-11T00:00:00</promotionStartDate>
    <promotionEndDate>2015-10-16T00:00:00</promotionEndDate>
  </promotion>
  <promotion>
    <promotionID>3</promotionID>
    <percentageOff>30</percentageOff>
    <promotionalMerchandise>Yes</promotionalMerchandise>
    <promotionStartDate>2015-09-02T00:00:00</promotionStartDate>
    <promotionEndDate>2015-09-07T00:00:00</promotionEndDate>
  </promotion>
  <promotion>
    <promotionID>4</promotionID>
    <percentageOff>5</percentageOff>
    <promotionalMerchandise>Yes</promotionalMerchandise>
    <promotionStartDate>2015-11-22T00:00:00</promotionStartDate>
    <promotionEndDate>2015-11-27T00:00:00</promotionEndDate>
  </promotion>
  <promotion>
    <promotionID>5</promotionID>
    <percentageOff>50</percentageOff>
    <promotionalMerchandise>No</promotionalMerchandise>
    <promotionStartDate>2015-08-13T00:00:00</promotionStartDate>
    <promotionEndDate>2015-08-18T00:00:00</promotionEndDate>
  </promotion>
  <promotion>
    <promotionID>6</promotionID>
    <percentageOff>80</percentageOff>
    <promotionalMerchandise>No</promotionalMerchandise>
    <promotionStartDate>2015-07-01T00:00:00</promotionStartDate>
    <promotionEndDate>2015-07-05T00:00:00</promotionEndDate>
  </promotion>
</bookstore>

我想达到什么目标?

对于每个<book></book>元素,我想使用<promotions></promotions>语句或捕获<xsl:for-each>数字ID的<template></template>循环关联的<promotionNum>在变量中,例如$IDNum

然后使用我的ID变量作为验证,我想将这个数字与六个<promotion>元素交叉引用。如果我们成功匹配,例如<xsl:for-each select="dataroot/Promotion"><xsl:if test="$IDNum">,然后我想在另一个变量中捕获<promotionEndDate>节点的值。

但这是重要部分,我想找到最新日期(或最大值)。因此,对于<title>Harry Potter and the Philosopher's Stone</title>,在四个相关促销元素(1-4)中,我希望从<promotionEndDate>2015-11-27T00:00:00</promotionEndDate>检索<promotion><promotionID>4</promotionID></promotion>(最新日期)。

我知道与XSLT 2.0不同,XSLT 1.0和日期不兼容,因此在创建存储<promotionEndDate></promotionEndDate>的变量时,需要有一个子串< /&#39; T&#39;然后翻译处理以丢失连字符,给你一个有效的数字,例如, 2015-11-27T00:00:00变为20151127(即数字)。

为什么呢?我想知道任何选定出版物的促销活动的最终日期。

使用XSLT 1.0可以实现吗?对于每个<promotionEndDate></promotionEndDate>节点,我可以运行子字符串/转换处理,然后使用一个模板在变量中捕获此日期值,然后将其与通过模板传递的下一个可用日期值进行比较。如果这个新数字是gt;,那么这将成为新的最高数字?

任何建议,一如既往都会受到热烈欢迎!!

1 个答案:

答案 0 :(得分:1)

使用交叉引用的密钥,然后在该日期对它们进行排序以找到最新的(最高编号):

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:key name="prom-by-id" match="bookstore/promotion" use="promotionID"/>

<xsl:template match="bookstore">
  <xsl:apply-templates select="book"/>
</xsl:template>

<xsl:template match="book">
  <xsl:copy>
     <xsl:copy-of select="title"/>
     <xsl:for-each select="key('prom-by-id', promotions/promotionNum)">
       <xsl:sort select="translate(promotionEndDate, '-T:', '')" data-type="number" order="descending"/>
       <xsl:if test="position() = 1">
         <xsl:copy-of select="."/>
       </xsl:if>
     </xsl:for-each>
   </xsl:copy>
</xsl:template>

</xsl:stylesheet>

您已经说过要将HTML作为输出,但是因为您没有显示任何XSLT代码,而是为book元素创建了HTML,我选择只输出book本身及其交叉引用promotion,当然您可以更改模板以输出HTML,查找促销的方法保持不变。