(1) Мое требование — преобразовать ДЕСЯТИЧНЫЙ ВВОД в шестнадцатеричную запись с фиксированными 8 цифрами
(2) Преобразуйте/сопоставьте ШЕСТНАДЦАТИЧНЫЙ РЕЗУЛЬТАТ с набором символов, выбирая по 2 ШЕСТНАДЦАТИЧНЫХ символа одновременно и добавляя соответствующие коды символов. Пожалуйста, обратитесь к ссылке ниже для кодировки символов
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/character-set-0127
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/character-set-128255
(3) Окончательная кодировка символов отображается как ВЫХОД
(4) Может ли XSLT обрабатывать все специальные наборы символов кодировки?
ДЕСЯТИЧНЫЙ ВВОД
<decimal>
<input>2<input>
<input>100<input>
<input>819<input>
<input>60<input>
</decimal>
Шестнадцатеричный результат
<input>
<hex>00000002</hex>
<hex>00000064</hex>
<hex>00000333</hex>
<hex>0000003C</hex>
</input>
ВЫВОД — КОДИРОВАНИЕ СИМВОЛОВ
<output>
<charset> </charset>
<charset> d</charset>
<charset> 3</charset>
<charset> <</charset>
</output>
Стоит отметить, что символ Юникода, код которого равен 2 (ваш первый шестнадцатеричный пример), недопустим в XML 1.0, поэтому вам может понадобиться <xsl:output method = "xml" version = "1.1"/>
в вашей таблице стилей, и вам может потребоваться убедиться, что процессор XSLT готов использовать XML 1.1. (что допускает более широкий диапазон допустимых символов, чем XML 1.0).
Ваш вопрос все еще не имеет смысла. Если ваш ожидаемый результат — символы, нет необходимости преобразовывать десятичные значения в шестнадцатеричную запись; вы можете просто использовать функцию codepoints-to-string()
для преобразования десятичных значений непосредственно в соответствующие символы Юникода. Однако (десятичный) код Unicode 819 представляет собой символ, ОБЪЕДИНЯЮЩИЙ ДВОЙНУЮ НИЖНЮЮ СТРОЧКУ, а не ТРИ ЦИФРЫ, которые вы показываете.
Ваше разъяснение о том, что кодовые точки во входных данных имеют длину 2 шестнадцатеричные цифры (8 бит), ссылку на Learn.microsoft.com/en-us/office/vba/language/reference/… и комментарий о «всех особенных специальные наборы символов кодировки» подразумевает, что символы, кодовые точки которых > 127, могут быть закодированы с использованием одной из различных «кодовых страниц». Эти кодировки символов не являются ASCII (это всего лишь 7-битная кодировка), и они также могут не быть Unicode. Знаете ли вы, что такое кодовая страница входных данных?
Некоторые из этих кодов находятся за пределами диапазона ASCII, но если под ASCII вы имеете в виду Unicode, вы можете попробовать
<xsl:value-of select = "concat('&#x', hex, ';')"
disable-output-escaping = "yes"/>
Спасибо @MichaelKay, это удовлетворяет потребность.
Обновлено: это ответ на исходный вопрос, в котором спрашивалось, как преобразовать шестнадцатеричное число в символ с помощью XSLT.
Я оставляю свой ответ здесь на случай, если он поможет кому-то с этой проблемой, хотя это не очень полезный ответ на вопрос, поскольку впоследствии он был отредактирован.
Вот альтернатива использованию XSLT 2.0, который, как мне кажется, поддерживается IBM DataPower.
XSLT 2.0 включает функцию codepoints-to-string
, которая может преобразовать кодовую точку (число) Юникода в строку. Но преобразование шестнадцатеричных цифр в целые числа по-прежнему является трудоемким делом (по крайней мере, я не знаю простого способа сделать это).
<xsl:stylesheet version = "2.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:hex = "http://example.com/hex"
xmlns:xs = "http://www.w3.org/2001/XMLSchema">
<xsl:output method = "xml" version = "1.1"/>
<xsl:function name = "hex:to-integer" as = "xs:integer">
<xsl:param name = "hex" as = "xs:string"/>
<xsl:variable name = "least-significant-digit"
select = "substring($hex, string-length($hex))"/>
<xsl:variable name = "most-significant-digits"
select = "substring($hex, 1, string-length($hex) - 1)"/>
<xsl:variable name = "hex-digit-value" select = "
string-length(
substring-before('0123456789ABCDEF', $least-significant-digit)
)
"/>
<xsl:choose>
<xsl:when test = "$most-significant-digits">
<xsl:sequence
select = "$hex-digit-value + 16 * hex:to-integer($most-significant-digits)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select = "$hex-digit-value"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match = "input">
<output>
<xsl:apply-templates/>
</output>
</xsl:template>
<xsl:template match = "hex">
<xsl:value-of select = "codepoints-to-string(hex:to-integer(.))"/>
</xsl:template>
</xsl:stylesheet>
Извините, но я обновил описание проблемы, добавив более точную информацию. Пожалуйста, просмотрите и дайте мне знать, если потребуется какая-либо дополнительная информация. Мне предстоит отладка устаревшего кода VB.Net 15-летней давности и его репликация в DataPower XSLT. Заранее спасибо.
Если ваш ввод на самом деле имеет десятичный формат, нет необходимости преобразовывать его в шестнадцатеричный. Не думайте, что XSLT должен использовать ту же процедуру, что и код VB, который вы портируете. Вы можете просто использовать арифметические операции по модулю с модулем 256.
Я собираюсь сделать предположение и предположить, что ваши входные значения представляют собой десятичные числа, каждое из которых представляет строку длиной до 4 символов, так что, например, строка "Char"
(которая в шестнадцатеричной записи будет представлена как 43 68 61 72
) вычисляется как десятичное значение объединенного шестнадцатеричного числа 43686172
= 1130914162
.
Теперь, чтобы декодировать такое число обратно в исходную строку, достаточно сделать:
XML
<input>
<decimal>67</decimal>
<decimal>17256</decimal>
<decimal>4417633</decimal>
<decimal>1130914162</decimal>
<decimal>100</decimal>
<decimal>51</decimal>
<decimal>60</decimal>
</input>
XSLT 2.0
<xsl:stylesheet version = "2.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:math = "http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes = "math">
<xsl:output method = "xml" version = "1.0" encoding = "UTF-8" indent = "yes"/>
<xsl:template match = "/input">
<output>
<xsl:for-each select = "decimal">
<xsl:variable name = "codes" select = "for $i in 0 to 3 return . idiv math:pow(256, $i) mod 256"/>
<charset>
<xsl:value-of select = "codepoints-to-string(reverse($codes[. > 0]))"/>
</charset>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
Результат
<?xml version = "1.0" encoding = "UTF-8"?>
<output>
<charset>C</charset>
<charset>Ch</charset>
<charset>Cha</charset>
<charset>Char</charset>
<charset>d</charset>
<charset>3</charset>
<charset><</charset>
</output>
Ваш вопрос не ясен. Каков ожидаемый результат входного примера и какая логика необходима для его получения? Термин «кодировка символов ASCII» для меня бессмысленен.