2010-03-27 5 views
1

При попытке сделать математику большого числа int64 большого числа в шаблоне xslt я получаю неправильный результат, поскольку в xslt нет встроенной 64-разрядной целочисленной поддержки (число xslt равно 64 -битный двойной). Я использую msxml 6.0 в Windows XP SP3. Есть ли какая-нибудь работа для этого в Windows?Обработка XSLT большого целого числа (int64) msxml

<tables> 
    <table> 
    <table_schem>REPADMIN</table_schem> 
    <table_name>TEST_DESCEND_IDENTITY_BIGINT</table_name> 
    <column> 
     <col_name>COL1</col_name> 
     <identity> 
     <col_min_val>9223372036854775805</col_min_val> 
     <col_max_val>9223372036854775805</col_max_val> 
     <autoincrementvalue>9223372036854775807</autoincrementvalue> 
     <autoincrementstart>9223372036854775807</autoincrementstart> 
     <autoincrementinc>-1</autoincrementinc> 
     </identity> 
    </column> 
    </table> 
</tables> 

Этот тест возвращает истину из-за неточное представление большого числа в 64-разрядной двойной (я предполагаю, что), но на самом деле это ложь, если я мог бы сказать, процессор XSLT как-то использовать int64, а не по умолчанию 64 -битовый двойной для числа данных, поскольку большое целое является фактическим типом данных для чисел в входе xml.

  <xsl:when test="autoincrementvalue = 
       (col_min_val + autoincrementinc)"> 
      <xsl:value-of select="''"/> 
      </xsl:when> 

здесь полный шаблон

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
    <!--Reseed Derby identity column--> 
    <xsl:output omit-xml-declaration='yes' method='text' /> 
    <xsl:param name="stmtsep">;</xsl:param> 
    <xsl:param name="schemprefix"></xsl:param> 
    <xsl:template match="tables"> 
    <xsl:variable name="identitycount" select="count(table/column/identity)"></xsl:variable> 
    <xsl:for-each select="table/column/identity"> 
     <xsl:variable name="table_schem" select="../../table_schem"></xsl:variable> 
     <xsl:variable name="table_name" select="../../table_name"></xsl:variable> 
     <xsl:variable name="tablespec"> 
     <xsl:if test="$schemprefix"> 
      <xsl:value-of select="$table_schem"/>.</xsl:if><xsl:value-of 
         select="$table_name"/></xsl:variable> 
     <xsl:variable name="col_name" select="../col_name"></xsl:variable> 
     <xsl:variable name="newstart"> 
     <xsl:choose> 
      <xsl:when test="autoincrementinc > 0"> 
      <xsl:choose> 
       <xsl:when test="col_max_val = '' and 
         autoincrementvalue = autoincrementstart"> 
       <xsl:value-of select="''"/> 
       </xsl:when> 
       <xsl:when test="col_max_val = ''"> 
       <xsl:value-of select="autoincrementstart"/> 
       </xsl:when> 
       <xsl:when test="autoincrementvalue = 
        (col_max_val + autoincrementinc)"> 
       <xsl:value-of select="''"/> 
       </xsl:when> 
       <xsl:when test="(col_max_val + autoincrementinc) &lt; 
         autoincrementstart"> 
       <xsl:value-of select="autoincrementstart"/> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:value-of select="col_max_val + autoincrementinc"/> 
       </xsl:otherwise>    
      </xsl:choose> 
      </xsl:when> 
      <xsl:when test="autoincrementinc &lt; 0"> 
      <xsl:choose> 
       <xsl:when test="col_min_val = '' and 
        autoincrementvalue = autoincrementstart"> 
       <xsl:value-of select="''"/> 
       </xsl:when> 
       <xsl:when test="col_min_val = ''"> 
       <xsl:value-of select="autoincrementstart"/> 
       </xsl:when> 
       <xsl:when test="autoincrementvalue = 
        (col_min_val + autoincrementinc)"> 
       <xsl:value-of select="''"/> 
       </xsl:when> 
       <xsl:when test="(col_min_val + autoincrementinc) > 
         autoincrementstart"> 
       <xsl:value-of select="autoincrementstart"/> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:value-of select="col_min_val + autoincrementinc"/> 
       </xsl:otherwise>    
      </xsl:choose> 
      </xsl:when>   
     </xsl:choose> 
     </xsl:variable> 
     <xsl:if test="not(position()=1)"><xsl:text> 
</xsl:text></xsl:if> 
     <xsl:choose> 
     <!--restart with ddl changes both the next identity value AUTOINCREMENTVALUE and 
     the identity start number AUTOINCREMENTSTART eventhough in this casewe only want 
     to change only the next identity number--> 
     <xsl:when test="$newstart != '' and 
         $newstart != autoincrementvalue">alter table <xsl:value-of 
select="$tablespec"/> alter column <xsl:value-of 
select="$col_name"/> restart with <xsl:value-of 
select="$newstart"/><xsl:if test="$identitycount>1">;</xsl:if></xsl:when> 
     <xsl:otherwise>-- reseed <xsl:value-of select="$tablespec"/> is not necessary</xsl:otherwise> 
      </xsl:choose> 
</xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

ответ

1

Есть ли какая-либо работа вокруг этого на Windows?

Нет, если вы не используете XSLT процессор 2.0, такие как Saxon или AltovaXML.

В XSLT 2.0 используется XPath 2.0, который поддерживает xs: decimal, и это дает вам требуемую точность. С Saxon можно также использовать только xs: integer, потому что и саксонская, и Altova реализуют арифметику Big Integer.

Вот 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 method="text"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "9223372036854775805 + (-1)"/> 
</xsl:template> 
</xsl:stylesheet> 

Оба саксонской 9.x и AltovaXML2010 произвести следующий правильный результат:

9223372036854775804 

Вот таблица стилей XSLT 2.0, которая использует xs: десятичное значение явно:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output method="text"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "xs:decimal(9223372036854775805) + (-1)"/> 
</xsl:template> 
</xsl:stylesheet> 

Оба саксонской 9.x и AltovaXML2010 снова производят правильный результат

+0

Спасибо за информацию. Я боюсь, что я застрял с msxml 6.0. Поскольку я генерирую входной XML из набора результатов в выражении sql select, жизнеспособным способом правильной математики является выполнение математики в операторе выбора базы данных и добавление элемента newstart во входной xml; то обработчик xslt вообще не выполнит математику и просто проверит на пустую строку для $ newstart для генерации вывода –

Смежные вопросы