【问题标题】:Converting Unicode-escaped characters with XSLT使用 XSLT 转换 Unicode 转义字符
【发布时间】:2014-10-21 15:41:28
【问题描述】:

谁能告诉我如何将 Unicode 代码点转义字符(如 \u00e4)转换为 XSLT 中的真实字符 ö

我确实有……

<text>Eine Repr\u00e4sentation des Objektes geh\u00f6rt...<text>

...我喜欢:

<text>Eine Repräsentation des Objektes gehört...<text>

【问题讨论】:

  • XSLT 1.0 还是 XSLT 2.0(或 3.0)?
  • XSLT 1.0 会很棒,但 XSLT 2.0 也很好。
  • 这样转义了多少个不同的字符?你有一个完整的列表,比如说,总共只有 3 次出现,总是相同的字符吗?只有变音符号?
  • 对于它的价值,这里有相反的代码:w3.org/TR/xslt-30/xml-to-json.xsl。您可能需要考虑如何处理代理对,其中两个连续的 \uxxxx 转义序列代表一个高代理和低代理,需要将它们组合成一个字符。

标签: xml xslt saxon


【解决方案1】:

这是一件多么有趣的事情...所以这是我想出的 XSLT 2.0 解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math f"
    xmlns:f="func" version="2.0">

    <xsl:template match="text">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="text/text()">
        <xsl:value-of select="f:unescapeCharachters(.)"/>
    </xsl:template>

    <xsl:function name="f:unescapeCharachters">
        <xsl:param name="text" as="xs:string"/>
        <xsl:analyze-string select="$text" regex="\\u([0-9|abcdefABCDEF]{{4}})">
            <xsl:matching-substring>
                <xsl:value-of select="codepoints-to-string(f:hex-to-dec(regex-group(1)))"/>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:function>

    <xsl:function name="f:hex-to-dec">
        <xsl:param name="hex"/>
        <xsl:variable name="hexvals" select="'0123456789ABCDEF'"/>
        <xsl:choose>
            <xsl:when test="$hex=''">0</xsl:when>
            <xsl:otherwise>
                <xsl:value-of
                    select="string-length(substring-before($hexvals,substring(upper-case($hex),1,1)))
                * math:pow(16,string-length($hex)-1) + f:hex-to-dec(substring($hex,2))"
                />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

</xsl:stylesheet>

【讨论】:

  • 很好,尽管您可能并不真的想将text() 传递给顶级函数调用,因为如果text 元素有多个文本,您将收到类型不匹配错误节点子。最好有一个匹配text/text() 并将. 传递给函数的模板。
  • @IanRoberts 感谢您的提示,您的权利......只是没有想到这个例子,更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 2014-05-05
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
相关资源
最近更新 更多