сравнение номеров с XSLT - PullRequest
       20

сравнение номеров с XSLT

2 голосов
/ 30 сентября 2010

В моем XML есть куча затрат, которые я пытаюсь сравнить с другим значением стоимости, чтобы определить, какие значения отображать (только те, которые выше, чем у компаратора). Это работает, когда числа используют десятичную точку в качестве разделителя, но не с числами, использующими запятую в качестве десятичного разделителя. Я мог бы получить либо, в зависимости от локали.

Вот что у меня есть:

<patron_max_cost><![CDATA[1,00]]></patron_max_cost>
<service_costs>
  <location_cost>
    <location_desc><![CDATA[location1]]></location_desc>
    <cost_to_user><![CDATA[0,99]]></cost_to_user>
  </location_cost>
  <location_cost>
      <location_desc><![CDATA[location2]]></location_desc>
      <cost_to_user><![CDATA[1,50]]></cost_to_user>
  </location_cost>
</service_costs>

<xsl:variable name="filtered_location_costs">
  <xsl:for-each select="service_costs/location_cost">
      <xsl:if test="number(cost_to_user) &gt; number(patron_max_cost)">
        <xsl:copy-of select="." />
      </xsl:if>
  </xsl:for-each>
</xsl:variable>

Это не удалось, потому что cost_to_user и patron_max_cost имеют значение NaN . Есть ли способ сделать это сравнение, которое будет работать для обоих стилей ввода и не включать в себя что-то хитрое, такое как преобразование запятых в десятичные точки перед сравнением? Я использую XSLT2.0 и Saxon8.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2010

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=
  "location_cost[not(translate(cost_to_user, ',', '.')
                     >
                     translate(/*/patron_max_cost, ',', '.')
                     )
                 ]
  "/>

</xsl:stylesheet>

при применении к предоставленному документу XML :

<t>
    <patron_max_cost><![CDATA[1,00]]></patron_max_cost>
    <service_costs>
        <location_cost>
            <location_desc><![CDATA[location1]]></location_desc>
            <cost_to_user><![CDATA[0,99]]></cost_to_user>
        </location_cost>
        <location_cost>
            <location_desc><![CDATA[location2]]></location_desc>
            <cost_to_user><![CDATA[1,50]]></cost_to_user>
        </location_cost>
    </service_costs>
</t>

дает желаемый результат :

<t>
   <patron_max_cost>1,00</patron_max_cost>
   <service_costs>
      <location_cost>
         <location_desc>location2</location_desc>
         <cost_to_user>1,50</cost_to_user>
      </location_cost>
   </service_costs>
</t>

II.Решение XSLT 2.0:

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

 <xsl:variable name="vpatron_max_cost" as="xs:decimal"
  select="xs:decimal(translate(/*/patron_max_cost, ',', '.'))"/>

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

 <xsl:template match=
  "location_cost[xs:decimal(translate(cost_to_user, ',', '.'))
                le
                 $vpatron_max_cost
                 ]
  "/>

</xsl:stylesheet>
0 голосов
/ 30 сентября 2010

Я бы использовал преобразование из запятой в десятичную, но также сохранил переменную того, была ли запятая в первую очередь, чтобы я мог правильно ее отобразить (т.е. преобразовать обратно.

...