xslt - 在 XSLT 中,如何将字符的十六进制代码作为文字文本?

标签 xslt character-encoding

我正在寻找各种转换,但我正在尝试获取构成已找到字符的十六进制字符串的实际字符串。所以,如果 XSLT

<xsl:analyze-string select="Message" regex="([&#x1f1;-&#x1f699;])">
        <xsl:non-matching-substring>
            <xsl:value-of select="."/>
        </xsl:non-matching-substring>
        <xsl:matching-substring>
            <xsl:variable name="emjtxt"/>...

遇到了XML
<Message>Very funny! 😋</Message>

稍后在 XSLT 中,我想要结果
<xsl:value-of select="$emjtxt"/>

...给出实际文本 '�' 而不是字符 '😋'

我试过代码点到字符串,但这没有帮助。一定有一些我没有找到的功能,因为我不确定如何在没有获得所有这些转换建议的情况下提出问题。

哦,我正在使用 XSLT 2 和 Saxon HE 9.4.0.4

提前致谢

最佳答案

这里什么算是有用的解决方案似乎可能取决于您为什么想要字符的十六进制表示。

如果您只希望输出具有数字字符引用 而不是 U+0020 到 U+007F 范围之外的字符的文字,最简单的方法是指定一个 xsl:output 编码值,该值命名一个不包括的字符集有问题的字符。输出这些字符时,它们将作为数字字符引用输出(您可能无法控制它们是十进制还是十六进制)。

如果是单个特定字符, 或少量字符,您感兴趣,最简单的解决方案是字符映射。从您的示例代码来看,我不认为是这种情况。

如果你想对十六进制值执行一些特殊的处理,,你需要一个函数,它将一个字符作为输入并返回表示输入字符的 UCS 代码点的十六进制数字。据我所知,没有内置函数可以做到这一点;也没有(除非我反复忽略它)是否有一个内置函数接受一个整数和一个基数并返回一个表示该基数中该整数的字符串。所以挑战是写一个。

最简单的解决方案将问题分解为两部分:首先,编写一个函数,它接受一个整数并返回该整数的十六进制表示。这是此类函数的简单实现(未测试):

<xsl:function name="my:i2x" as="xs:string">
  <xsl:param name="i" as="xs:integer"/>
  <xsl:choose>
    <xsl:when test="$i lt 0">
      <xsl:value-of select="concat('-', my:i2x(-1 * $i))"/>
    </xsl:when>
    <xsl:when test="$i eq 0">
      <xsl:value-of select="'0'"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="quot" select="$i idiv 16"/>
      <xsl:variable name="rmdr" select="$i mod 16"/>
      <xsl:value-of select="concat(
          my:i2x($quot),
          substring('0123456789ABCDEF', $rmdr + 1, 1)
        )"
      />
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

现在很容易编写一个包装函数来接受一个字符并在该字符的代码点上调用 local:i2x() :
<xsl:function name="my:c2x" as="xs:string ">
  <xsl:param name="s" as="xs:string"/>
  <xsl:choose>
    <xsl:when test="string-length($s) != 1">
      <xsl:message terminate="yes">
        The argument to local:c2x should be a single character, 
        not a longer or shorter string.
      </xsl:message>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="my:i2x(string-to-codepoints($s))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

如果你愿意,你可以让 c2x() 返回一个数字字符引用(但是当你尝试序列化它时要小心,以免你得到 &amp;#x01F60B; 而不是 &#x01F60B; 。(如上所述——如果你想要的只是得到数字输出中的字符引用而不是文字,这不是要采用的方法。)

关于xslt - 在 XSLT 中,如何将字符的十六进制代码作为文字文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17203624/

相关文章:

使用分隔符时的 XML 格式编号问题

xslt - SpecFlow 的自定义报告

java - JSP中的UTF GET参数编码问题(JBoss 2.0.1)

unicode - HTML Agility Pack 的编码错误

utf-8 - 在 ZPL 中打印带有尖号的字符

xml - 在 XSLT 中对具有条件的记录进行计数

xslt - 如何在 Tomcat 中设置 XSLT 2.0?

xml - 通过匹配另一个节点名称来获取节点或通过匹配另一个节点来排除节点

java - 从 "UTF-8"转换为 "ISO-8859-1"时,除 0x00-0x7F 之外的字符不显示

PHP 自定义编码函数没有给出所需的结果