Domanda

Ho un documento XML in cui il numero di cifre decimali un particolare xs:decimal deve essere segnalato in si svolge in un nodo di pari livello. Attualmente sto lottando per trovare un modo semplice per uscita questo tramite la funzione format-number.

posso costruire una stringa foto con alcune altre funzioni, ma questo sembra terribilmente prolisso per quello che dovrebbe essere (almeno IMO) un compito relativamente semplice e comune.

es. quello che sto facendo attualmente è qualcosa di simile:

<xsl:value-of
 select="format-number(myNode/DecimalValue,
         concat('#0.', 
                string-join(for $i in 1 to myNode/DecimalPlaces return '0'))"
/>

C'è un modo migliore?

È stato utile?

Soluzione

Domanda molto buono! Che di solito significa, non so la risposta, ma spero che qualcun altro lo fa in quanto questo è un dolore per me.

In ogni caso, ho fatto qualche ricerca e penso che la funzione round-half-to-even potrebbe fare il trucco ( http://www.xqueryfunctions.com/xq/fn_round-half-to-even.html )

Il tuo codice sarebbe diventato:

<xsl:value-of 
  select="
    round-half-to-even(
      myNode/DecimalValue
    , myNode/DecimalPlaces
    )
  "
/>

Ora fuori per un po 'di tangente: Per le persone che utilizzano XSLT 1.1 o inferiore e XPath 1, è possibile utilizzare questo:

<xsl:value-of 
  select="
    concat(
      substring-before(DecimalValue, '.')
    , '.'
    , substring(substring-after(DecimalValue, '.'), 1, DecimalPlaces -1)
    , round(
        concat(
          substring(substring-after(DecimalValue, '.'), DecimalPlaces, 1)
        ,   '.'
        ,   substring(substring-after(DecimalValue, '.'), DecimalPlaces+1)
        )
      )
    )
  "
/>

Naturalmente, questo codice è peggio di quella originale, ma se qualcuno sa come risolvere il problema originale per XPath 1 e ha un'idea migliore di questo, mi piacerebbe sentire che. (Sempre più spesso, vorrei che il mondo sarebbe saltato XML del tutto e si trasferisce immediatamente a JSON)

Altri suggerimenti

<!-- use a generous amount of zeros in a top-level variable -->
<xsl:variable name="zeros" select="'000000000000000000000000000000000'" />

<!-- …time passes… -->
<xsl:value-of select="
  format-number(
     myNode/DecimalValue,
     concat('#0.', substring($zeros, 1, myNode/DecimalPlaces))
  )
" />

Si può astrarre via in un template:

<!-- template mode is merely to prevent collisions with other templates -->
<xsl:template match="myNode" mode="FormatValue">
  <xsl:value-of select="
    format-number(
      DecimalValue, 
      concat('#0.', substring($zeros, 1, DecimalPlaces))
    )
  " />
</xsl:template>

<!-- call like this -->
<xsl:apply-templates select="myNode" mode="FormatValue" />

Si può anche fare un modello di nome e utilizzare il nodo di contesto XSLT quando si chiama esso. Dipende un po 'sul vostro documento di input e ha bisogno se questo è fattibile per voi.

<xsl:template name="FormatValue">
  <!-- same as above -->
</xsl:template>

<!-- call like this -->
<xsl:for-each select="myNode">
  <xsl:call-template name="FormatValue" />
</xsl:for-each>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top