Here's how I do it without using XSLT:
Hex to number
160 * translate(substring(Offsets/Offset/Value,1,1), '0123456789ABCDEFabcdef', '0000000000111111111111') + 16 * translate(substring(Offsets/Offset/Value,1,1), '0123456789ABCDEFabcdef', '0123456789012345012345') + 10 * translate(substring(Offsets/Offset/Value,2,1), '0123456789ABCDEFabcdef', '0000000000111111111111') + translate(substring(Offsets/Offset/Value,2,1), '0123456789ABCDEFabcdef', '0123456789012345012345')
The inverse function is simpler:
concat( substring('0123456789ABCDEF', valueDecimal / 16 ,1) , substring('0123456789ABCDEF', valueDecimal mod 16 ,1) )
Both suggest that your hexadecimal digits always have two digits.
source share