通缉:xsl:将节点转换为hexavigesimal值的模板?

时间:2012-05-25 09:36:52

标签: .net xslt hexavigesimal

我几乎可以在这里说:“@ ## $#是hexavigesimal值是什么?”

  

六进制数字系统具有二十六个基数。   或者,可以仅使用字母表示基数26   拉丁字母。由于英语中有26个字母,所以26个字母也是   这是可能的最高基础,因此利用每一个   信件。 0表示A,1 = B,2 = C ... 24 = Y,25 = Z.一些   例子:26 = AA,30 = BE

所以它基本上是Excel使用列描述。我想有一个函数将具有int值的节点转换为该值。

来源:

<root>
  <row>12</row>
  <column>23</column>
</root>

我想通过调用执行转换的模板将column打印为X。可以吗?

3 个答案:

答案 0 :(得分:1)

试试这个XSLT ......

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:variable name="symbols" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
   <xsl:variable name="symbols-count" select="string-length($symbols)" />
   <xsl:template match="row">
      <row>
      <xsl:call-template name="convert" />
      </row>
   </xsl:template>

   <xsl:template name="convert">
      <xsl:param name="value" select="number(.)" />
      <xsl:choose>
         <xsl:when test="$value >= $symbols-count">
            <xsl:variable name="div" select="floor($value div $symbols-count)" />
            <xsl:variable name="remainder" select="$value - $div * $symbols-count" />
            <xsl:call-template name="convert">
               <xsl:with-param name="value" select="$div" />
            </xsl:call-template>
            <xsl:value-of select="substring($symbols, $remainder + 1, 1)" />
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="substring($symbols, $value + 1, 1)" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

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

应用于以下XML

<root>
   <row>12</row>
   <column>23</column>
   <row>26</row>
   <column>23</column>
</root>

以下是输出

<root>
  <row>M</row>
  <column>23</column>
  <row>BA</row>
  <column>23</column>
</root>

您应该能够调整符号变量,以允许任何奇特的命名转换。例如,要转换为十六进制,请将其更改为以下

<xsl:variable name="symbols" select="'0123456789ABCDEF'" />

和二进制

<xsl:variable name="symbols" select="'01'" />

答案 1 :(得分:0)

您可能会发现<xsl:number value="$n" format="A"/>符合您的要求,但并不能保证。

答案 2 :(得分:0)

在XSLT 1.0中使用

 <xsl:template name="toHex">
   <xsl:param name="decimalNumber" />
   <xsl:if test="$decimalNumber >= 16">
     <xsl:call-template name="toHex">
       <xsl:with-param name="decimalNumber" 
              select="floor($decimalNumber div 16)" />
       </xsl:call-template>
   </xsl:if>
   <xsl:value-of select=
      "substring($hexDigits, ($decimalNumber mod 16) + 1, 1)" />
 </xsl:template>

其中$hexDigits是字符串'0123456789ABCDEF'

以下是完整示例

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

    <xsl:variable name="hexDigits" select="'0123456789ABCDEF'"/>

    <xsl:template match="/*">
      <xsl:call-template name="toHex"/>
    </xsl:template>

    <xsl:template name="toHex">
        <xsl:param name="decimalNumber" select="." />
        <xsl:if test="$decimalNumber >= 16">
            <xsl:call-template name="toHex">
                <xsl:with-param name="decimalNumber" select=
                  "floor($decimalNumber div 16)" />
            </xsl:call-template>
        </xsl:if>
        <xsl:value-of select=
         "substring($hexDigits, ($decimalNumber mod 16) + 1, 1)" />
    </xsl:template>
</xsl:stylesheet>

在此XML文档上应用此XSLT 1.0转换时:

<t>12345</t>

产生了想要的正确结果:

3039

另请参阅我对此问题的回答

https://stackoverflow.com/a/3053656/36305