XSLT循环和Ifs

时间:2017-10-23 10:38:01

标签: xml xslt

我有一个XML响应的片段如下:

<?xml version="1.0" encoding="utf-8"?>
<Envelope>
    <Body>
        <Response>
            <Result>
                <ErrorCode>0</ErrorCode>
                <ErrorDescription>Success</ErrorDescription>
                <Instances>
                    <Instance>
                      <ID>3333</ID>
                      <RoundCode>AM</RoundCode>
                      <ScheduleName>Tue</ScheduleName>
                      <Date>2017-10-24T00:00:00</Date>
                      <SlotsFree>0</SlotsFree>
                      <SlotsTaken>10</SlotsTaken>
                    </Instance>
                    <Instance>
                        <ID>4444</ID>
                        <RoundCode>PM</RoundCode>
                        <ScheduleName>Tue</ScheduleName>
                        <Date>2017-10-24T00:00:00</Date>
                        <SlotsFree>10</SlotsFree>
                        <SlotsTaken>0</SlotsTaken>
                    </Instance>
                </Instances>
            </Result>
        </Response>
    </Body>
</Envelope>

如果它们小于10,我需要它显示所有AM插槽,如果它们大于或等于10,则显示PM插槽(对于选定的日期(在这种情况下,Tue))。我已尝试循环,但因为传递给它的数据将始终满足其中一个条件,因此显示AM和PM。我需要代码来显示AM,如果它不能,则显示PM。鉴于此尝试使用XSL:when和XSL:如果仍然无法为此获得任何有效的转换。

我的当前XSLT和HTML如下所示,如果有人有任何建议,我们将不胜感激。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr bgcolor="#9acd32">
      <th>ID</th>
      <th>ScheduleName</th>
      <th>Date</th>
      <th>SlotsFree</th>
      <th>SlotsTaken</th>
      <th>RoundCode</th>
    </tr>
    <xsl:for-each select="Envelope/Body/Response/Result/Instances/Instance">

  <xsl:choose>
    <xsl:when test="ScheduleName='Mon' and contains(RoundCode,'AM') and SlotsTaken &lt; 10">
      <tr>
        <td><xsl:value-of select="ID"/></td>
        <td><xsl:value-of select="ScheduleName"/></td>
        <td><xsl:value-of select="concat(substring(substring(Date,1,10),9,2),'/',substring(substring(Date,1,10),6,2),'/',substring(substring(Date,1,10),1,4))"/><xsl:value-of select="concat(' (',SlotsFree,' Slots Remaining!)')"/></td>
        <td><xsl:value-of select="SlotsFree"/></td>
        <td><xsl:value-of select="SlotsTaken"/></td>
        <td><xsl:value-of select="RoundCode"/></td>
      </tr>
    </xsl:when>
  </xsl:choose>

    </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

考虑使用密钥按Instance

查找Date个元素
 <xsl:key name="days" match="Instance" use="Date" />

然后,要获得AM个小于10的广告位,或者PM,则可以为xsl:for-each添加条件

试试这个XSTL

<xsl:for-each 
     select="Envelope/Body/Response/Result/Instances/Instance
             [(RoundCode = 'AM' and SlotsTaken &lt; 10) 
                or (RoundCode = 'PM' and not(key('days', Date)[RoundCode = 'AM' and SlotsTaken &lt; 10]))]">

试试这个XSLT

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

<xsl:key name="days" match="Instance" use="Date" />
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr bgcolor="#9acd32">
      <th>ID</th>
      <th>ScheduleName</th>
      <th>Date</th>
      <th>SlotsFree</th>
      <th>SlotsTaken</th>
      <th>RoundCode</th>
    </tr>
    <xsl:for-each select="Envelope/Body/Response/Result/Instances/Instance[(RoundCode = 'AM' and SlotsTaken &lt; 10) or (RoundCode = 'PM' and not(key('days', Date)[RoundCode = 'AM' and SlotsTaken &lt; 10]))]">
      <tr>
        <td><xsl:value-of select="ID"/></td>
        <td><xsl:value-of select="ScheduleName"/></td>
        <td><xsl:value-of select="concat(substring(substring(Date,1,10),9,2),'/',substring(substring(Date,1,10),6,2),'/',substring(substring(Date,1,10),1,4))"/><xsl:value-of select="concat(' (',SlotsFree,' Slots Remaining!)')"/></td>
        <td><xsl:value-of select="SlotsFree"/></td>
        <td><xsl:value-of select="SlotsTaken"/></td>
        <td><xsl:value-of select="RoundCode"/></td>
      </tr>
     </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

使用版本2.0,这适用于http://xslttest.appspot.com/但不适用于我的FF浏览器,我不确定原因。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>ID</th>
        <th>ScheduleName</th>
        <th>Date</th>
        <th>SlotsFree</th>
        <th>SlotsTaken</th>
        <th>RoundCode</th>
      </tr>
      <xsl:for-each-group select="Envelope/Body/Response/Result/Instances/Instance[SlotsTaken &lt; 10 and (contains(RoundCode,'AM') or contains(RoundCode,'PM'))]" group-by="ScheduleName">
        <tr>
          <td><xsl:value-of select="./ID"/></td>
          <td><xsl:value-of select="./ScheduleName"/></td>
          <td><xsl:value-of select="concat(substring(substring(./Date,1,10),9,2),'/',substring(substring(./Date,1,10),6,2),'/',substring(substring(./Date,1,10),1,4))"/><xsl:value-of select="concat(' (',./SlotsFree,' Slots Remaining!)')"/></td>
          <td><xsl:value-of select="./SlotsFree"/></td>
          <td><xsl:value-of select="./SlotsTaken"/></td>
          <td><xsl:value-of select="./RoundCode"/></td>
        </tr>
      </xsl:for-each-group>            
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>