XSLT:按 2 个值中较低的值排序 [英] XSLT: Sort by the lower of 2 values

查看:32
本文介绍了XSLT:按 2 个值中较低的值排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些格式如下的 XML:

I have some XML that is formatted as follows:

<products>
  <product>
    <name>Product 1</name>
    <price>
      <orig>15</orig>
      <offer>10</offer>
    </price>
  </product>
  <product>
    <name>Product 2</name>
    <price>
      <orig>13</orig>
      <offer>12</offer>
    </price>
  </product>
  <product>
    <name>Product 3</name>
    <price>
      <orig>11</orig>
    </price>
  </product>
</products>

我需要根据当前价格使用 XSLT 1.0(升序或降序)对产品进行排序.我的困难在于我需要对两个可能的价格值 if 中的较低者进行排序> 它们都存在.

I need to sort the products using XSLT 1.0 (in either ascending or descending order) based on their current price. My difficulty lies in the fact that I need to sort on the lower of the two possible price values <orig> and <offer> if they both exist.

对于上面的例子,正确的顺序是:

For the above example the correct ordering would be:

  • 产品 1(最低值 = 10)
  • 产品 3(最低值 = 11)
  • 产品 2(最低值 = 12)

任何帮助将不胜感激,因为我似乎无法通过搜索找到类似的问题.

Any help would be much appreciated, as I can't seem to find a similar question through the search.

推荐答案

I.有一个通用的纯 XSLT 1.0 解决方案——就这么简单:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <products>
   <xsl:apply-templates select="*">
    <xsl:sort data-type="number" select=
    "price/*[not(../* &lt; .)]"/>
   </xsl:apply-templates>
  </products>
 </xsl:template>
</xsl:stylesheet>

<小时>

二.如果 price 除了 offerorig 之外还有其他子节点——在这种情况下,一般的解决方案 I.以上(以及此问题的其他两个答案)无法正常工作.


II. If price has other children in addition to offer and orig -- in this case the general solution I. above (as well as the other two answers to this question) doesn't work correctly.

对于这种情况,这是一个正确的解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <products>
   <xsl:apply-templates select="*">
    <xsl:sort data-type="number" select=
    "sum(price/orig[not(../offer &lt;= .)])
   +
     sum(price/offer[not(../orig &lt; .)])
    "/>
   </xsl:apply-templates>
  </products>
 </xsl:template>
</xsl:stylesheet>

<小时>

三.如果我们知道 offer 永远不会超过 orig:


III. If we know that offer never exceeds orig:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <products>
   <xsl:apply-templates select="*">
    <xsl:sort data-type="number" 
         select="price/offer | price/orig[not(../offer)]"/>
   </xsl:apply-templates>
  </products>
 </xsl:template>
</xsl:stylesheet>

四.验证:

当应用于提供的 XML 文档时,上述所有三个转换:

All three transformations above, when applied to the provided XML document:

<products>
  <product>
    <name>Product 1</name>
    <price>
      <orig>15</orig>
      <offer>10</offer>
    </price>
  </product>
  <product>
    <name>Product 2</name>
    <price>
      <orig>13</orig>
      <offer>12</offer>
    </price>
  </product>
  <product>
    <name>Product 3</name>
    <price>
      <orig>11</orig>
    </price>
  </product>
</products>

产生想要的、正确的结果:

<products>
   <product>
      <name>Product 1</name>
      <price>
         <orig>15</orig>
         <offer>10</offer>
      </price>
   </product>
   <product>
      <name>Product 3</name>
      <price>
         <orig>11</orig>
      </price>
   </product>
   <product>
      <name>Product 2</name>
      <price>
         <orig>13</orig>
         <offer>12</offer>
      </price>
   </product>
</products>

解决方案 II 是三个中唯一在应用于此 XML 文档时仍能产生正确结果的方法(在 price):

<products>
  <product>
    <name>Product 1</name>
    <price>
      <orig>15</orig>
      <offer>10</offer>
      <minAcceptable>8</minAcceptable>
    </price>
  </product>
  <product>
    <name>Product 2</name>
    <price>
      <orig>13</orig>
      <offer>12</offer>
      <minAcceptable>6</minAcceptable>
    </price>
  </product>
  <product>
    <name>Product 3</name>
    <price>
      <orig>11</orig>
      <minAcceptable>7</minAcceptable>
    </price>
  </product>
</products>

请注意其他答案均未正确处理此 XML 文档.

Do note that none of the other answers processes this XML document correctly.

这篇关于XSLT:按 2 个值中较低的值排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆