2010-03-27 6 views
1

xslt 템플릿에서 큰 정수 (int64) 큰 숫자를 계산하려고 할 때 xslt에 원시 64 비트 정수가 지원되지 않으므로 잘못된 결과가 발생합니다 (xslt 숫자는 64입니다. -bit double). Windows XP SP3에서 msxml 6.0을 사용하고 있습니다. Windows에서이 문제를 해결할 수 있습니까?msxml을 처리하는 XSLT 큰 정수 (int64)

<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 비트 이중에서 큰 정수 (나는 가정입니다)의 부정확 한 표현에 true를 돌려 실제로 어떻게 든 XSLT 프로세서를 말할 수있는 기본 64보다는 INT64 사용하는 경우는 false입니다 -bit는 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에게 같은 색슨 또는 AltovaXML로 2.0 프로세서를 사용하지 않는.

XSLT 2.0에서는 xs : decimal을 지원하는 XPath 2.0이 사용되며 이에 따라 필요한 정밀도가 제공됩니다. Saxon과 Altova는 모두 Big Integer 산술을 구현하기 때문에 Saxon을 사용하면 xs : integer 만 사용할 수도 있습니다.

9223372036854775804 
:

<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 다음 올바른 결과 생산 : 여기

는 XSLT 2.0 스타일 시트 (기본 정수 즉 XS를 사용)이며

다음은 xs : decimal을 명시 적으로 사용하는 XSLT 2.0 스타일 시트입니다. :

012 3,516,
<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에 당장 붙어있다. SQL select 문에서 결과 집합으로부터 입력 xml을 생성하기 때문에 수학을 올바르게 수행 할 수있는 방법은 데이터베이스 select 문에서 수학을 수행하고 input xml에 newstart 요소를 추가하는 것입니다. 그러면 xslt 프로세서가 전혀 계산을하지 않고 출력을 생성하기 위해 $ newstart의 빈 문자열을 확인합니다 –