2010-07-29 5 views
2

중> 번호 -> 출력 입력 - 처리 중에 자릿수 보관 : XML 내용이 XSLT 들어 XSLT 처리

<xsl:variable name="source0" select="number(num2)"/> 
    <xsl:variable name="source1" select="number(num3)"/> 
    s0 plain: <xsl:value-of select="$source0"/> 
    s1 plain: <xsl:value-of select="$source1"/> 
    test11: <xsl:value-of select="format-number($source0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($source0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($source1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($source1, '#.###############')"/> 

:

<num2>123456.1234</num2> 
<num3>1234567.1234</num3> 

가 I (이 출력을 얻을 슨 9.2 XSLT를 사용하여 2.0)

s0 plain: 123456.1234 
    s1 plain: 1.2345671234E6 
    test11: 123456.1 
    test12: 123456.123399999996764 
    test21: 1234567.1 
    test22: 1234567.123399999924004 

우선 ... 나는 왜 갑자기 표준과 과학 표기법을 전환하는지 궁금하다. 소숫점 왼쪽 6 자리 숫자는? 이것이 나의 문제입니다. 과학 표기법을 피하고 싶습니다. 여러 가지 다른 질문을 한 후에, 나는 형식 번호를 도처에 두는 것에 매달려 있음을 발견했다.

하지만 format-number는 작동하지 않습니다. "s1 plain"의 출력이 유효 숫자가 프로세서에 알려졌다는 사실에도 불구하고 (double과 back로 변환하는 것은 정밀도를 떨어 뜨릴 수 있다는 것을 이해하지만 이러한 변환 후에 올바른 숫자가 있으므로 ...?) 표준 비 과학 표기법으로 그 값을 출력 할 수있는 방법이없는 것처럼 보입니다. 거기 있니?

+0

좋은 질문 (+1). 최대 정확도를 달성하는 솔루션에 대한 내 대답을 참조하십시오. –

+0

이중 -> 문자열 변환에 대한 XSLT 2.0 사양에 따르면 값이 1e-6에서 1e + 6 범위를 벗어나는 경우 지수 표기법을 사용해야합니다. 그 컷오프 포인트는 물론 완전히 임의적이지만, 1e215가 길이로 쓰여지는 것을 원하지는 않을 것입니다 ... –

+0

"유효 자릿수는 프로세서에 알려져 있습니다"라고 생각하는 것은 잘못입니다. 사용 된 알고리즘에 대해 더 알고 싶다면 Saxon의 변환은 유명한 논문 인 http://portal.acm.org/citation.cfm?id=93559를 기반으로합니다. –

답변

2

이것은 내 문제입니다. 나는 과학 표기법을 피하고 싶습니다. 다양한 다른 질문이 있은 후, 나는 분명히 발견했습니다. 형식 번호 : 을 사방에 배치하는 데 어려움이 있습니다.

그러나 형식 번호는 중 하나에 나타나지 않습니다.

분명히 XSLT 2.0/XPath 2.0의 적절한 기능을 사용하고 있지 않습니다.

이 변환이 XML 문서에 적용

<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:variable name="vs0" as="xs:decimal" 
    select="xs:decimal(num2)"/> 

    <xsl:variable name="vs1" as="xs:decimal" 
    select="xs:decimal(num3)"/> 

    s0 plain: <xsl:value-of select="$vs0"/> 
    s1 plain: <xsl:value-of select="$vs1"/> 
    test11: <xsl:value-of select="format-number($vs0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($vs0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($vs1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($vs1, '#.###############')"/> 

</xsl:template> 
</xsl:stylesheet> 

:

<nums> 
    <num2>123456.1234</num2> 
    <num3>1234567.1234</num3> 
</nums> 

가 생산 정확한 결과 :

s0 plain: 123456.1234 
s1 plain: 1234567.1234 
test11: 123456.1 
test12: 123456.1234 
test21: 1234567.1 
test22: 1234567.1234 

결론 : 좋은 정밀도가 필요한 경우 항상 xs:decimal 데이터 유형을 사용해보십시오.

+0

+1 좋은 답변입니다! @taotree : 이것은 다른 질문에서 "casting"이라고 쓰고 "내장 데이터 형식 생성자"를 사용하는 것입니다. –

+0

실제로 xs : decimal을 사용할 때는 format-number를 사용할 필요가 없습니다.당신이해야 할 일은 xs : decimal에 캐스팅하는 것뿐입니다. 항상 십진수 (비 과학적) 표기법으로 출력됩니다. number()는 용서하지만 xs : decimal()은 그렇지 않기 때문에 빈 문자열을 확인해야했습니다. if (string-length (normalize-space ($ value))> 0) if xs : decimal ($ value) else number ($ value) – mentics