XSLT:将字符串的特定字符单独转换为字符串*包括*它们的十六进制值
XSLT: Convert specific characters of a string individually to a string *including* their values in hex
我需要一些帮助,将一些 8 位 ASCII 字符转换为包含其十六进制值的字符串。我想将德语变音符号 (äöüÄÖÜß) 转换为其十六进制 RTF 表示形式。例如字符 ä
应转换为 \'E4
.
我知道其他字符转换解决方案,例如 xslt: converting characters to their hexadecimal Unicode representation。但是当我尝试将它与 xsl:replace()
结合使用时,只有 $
字符被转换,而不是匹配组 [=16=]
的结果。
这就是我尝试过的方法。我在样式表的某处使用它来转换字符串的一些字符:
<xsl:value-of select="replace($rtfText, '[äöüßÄÖÜ]', at:char-to-unicode('[=10=]'))"/>
at:int-to-hex
是函数,来自另一个问题。我认为在另一个函数中使用它是个好主意:
<xsl:function name="at:char-to-unicode" as="xs:string">
<xsl:param name="in" as="xs:string"/>
<xsl:sequence select="concat('\''', at:int-to-hex(string-to-codepoints('$in')[1]))"/>
</xsl:function>
<xsl:function name="at:int-to-hex" as="xs:string">
<xsl:param name="in" as="xs:integer"/>
<xsl:sequence
select="if ($in eq 0)
then '0'
else
concat(if ($in gt 16)
then at:int-to-hex($in idiv 16)
else '',
substring('0123456789ABCDEF',
($in mod 16) + 1, 1))"/>
</xsl:function>
有人可以帮忙吗?
如您所说,您使用 XSLT 2 或 3 并希望替换完整输出文档中的字符,我认为使用字符映射是最简单的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="text" use-character-maps="rtf-hex"/>
<xsl:character-map name="rtf-hex">
<xsl:output-character character="ä" string="\'E4"/>
<xsl:output-character character="ö" string="\'F6"/>
<xsl:output-character character="ü" string="\'FC"/>
<xsl:output-character character="Ä" string="\'C4"/>
<xsl:output-character character="Ö" string="\'D6"/>
<xsl:output-character character="Ü" string="\'DC"/>
<xsl:output-character character="ß" string="\'DF"/>
</xsl:character-map>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPzifpr/1 有个例子。
在 XSLT 3 中,由于 serialize
函数及其第二个参数,您还可以在字符串上本地使用字符映射,您可以在其中将字符映射定义为 XPath 3.1 map(xs:string, xs:string)
例如
serialize(., map { "method" : "text", "use-character-maps" : map{"Ä":"\C4","ä":"\E4","Ö":"\D6","ö":"\F6","Ü":"\DC","ü":"\FC","ß":"\DF"} })
应用映射所以
<text xml:lang="de">Dies ist ein Test mit Umlauten: ä, ö, ü, ß, Ä, Ö, Ü.</text>
将由
转换
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml"/>
<xsl:template match="text">
<xsl:copy>
<xsl:value-of select='serialize(., map { "method" : "text", "use-character-maps" : map{"Ä":"\C4","ä":"\E4","Ö":"\D6","ö":"\F6","Ü":"\DC","ü":"\FC","ß":"\DF"} })'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
到
<text>Dies ist ein Test mit Umlauten: \E4, \F6, \FC, \DF, \C4, \D6, \DC.</text>
我意识到最后一个示例没有您描述的确切替换,但是当我尝试动态生成使用过的地图并且 运行 遇到 Saxon 生成正确语法以使用内部地图的问题对于 XSLT 属性,您需要将 map{"Ä":"\C4"
等值固定为 map{"Ä":"\'C4"
.
至于基于正则表达式的匹配和替换它们,在 XSLT 3.0 中使用 analyze-string
函数你可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:function name="mf:int-to-hex" as="xs:string">
<xsl:param name="int" as="xs:integer"/>
<xsl:sequence
select="if ($int eq 0)
then '0'
else concat(
if ($int gt 16)
then mf:int-to-hex($int idiv 16) else '',
substring('0123456789ABCDEF', ($int mod 16) + 1, 1)
)"/>
</xsl:function>
<xsl:template match="text()">
<xsl:value-of select="analyze-string(., '\p{IsLatin-1 Supplement}')/*/(if (. instance of element(fn:match)) then '\''' || mf:int-to-hex(string-to-codepoints(.)) else string())" separator=""/>
</xsl:template>
</xsl:stylesheet>
我需要一些帮助,将一些 8 位 ASCII 字符转换为包含其十六进制值的字符串。我想将德语变音符号 (äöüÄÖÜß) 转换为其十六进制 RTF 表示形式。例如字符 ä
应转换为 \'E4
.
我知道其他字符转换解决方案,例如 xslt: converting characters to their hexadecimal Unicode representation。但是当我尝试将它与 xsl:replace()
结合使用时,只有 $
字符被转换,而不是匹配组 [=16=]
的结果。
这就是我尝试过的方法。我在样式表的某处使用它来转换字符串的一些字符:
<xsl:value-of select="replace($rtfText, '[äöüßÄÖÜ]', at:char-to-unicode('[=10=]'))"/>
at:int-to-hex
是函数,来自另一个问题。我认为在另一个函数中使用它是个好主意:
<xsl:function name="at:char-to-unicode" as="xs:string">
<xsl:param name="in" as="xs:string"/>
<xsl:sequence select="concat('\''', at:int-to-hex(string-to-codepoints('$in')[1]))"/>
</xsl:function>
<xsl:function name="at:int-to-hex" as="xs:string">
<xsl:param name="in" as="xs:integer"/>
<xsl:sequence
select="if ($in eq 0)
then '0'
else
concat(if ($in gt 16)
then at:int-to-hex($in idiv 16)
else '',
substring('0123456789ABCDEF',
($in mod 16) + 1, 1))"/>
</xsl:function>
有人可以帮忙吗?
如您所说,您使用 XSLT 2 或 3 并希望替换完整输出文档中的字符,我认为使用字符映射是最简单的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="text" use-character-maps="rtf-hex"/>
<xsl:character-map name="rtf-hex">
<xsl:output-character character="ä" string="\'E4"/>
<xsl:output-character character="ö" string="\'F6"/>
<xsl:output-character character="ü" string="\'FC"/>
<xsl:output-character character="Ä" string="\'C4"/>
<xsl:output-character character="Ö" string="\'D6"/>
<xsl:output-character character="Ü" string="\'DC"/>
<xsl:output-character character="ß" string="\'DF"/>
</xsl:character-map>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPzifpr/1 有个例子。
在 XSLT 3 中,由于 serialize
函数及其第二个参数,您还可以在字符串上本地使用字符映射,您可以在其中将字符映射定义为 XPath 3.1 map(xs:string, xs:string)
例如
serialize(., map { "method" : "text", "use-character-maps" : map{"Ä":"\C4","ä":"\E4","Ö":"\D6","ö":"\F6","Ü":"\DC","ü":"\FC","ß":"\DF"} })
应用映射所以
<text xml:lang="de">Dies ist ein Test mit Umlauten: ä, ö, ü, ß, Ä, Ö, Ü.</text>
将由
转换<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml"/>
<xsl:template match="text">
<xsl:copy>
<xsl:value-of select='serialize(., map { "method" : "text", "use-character-maps" : map{"Ä":"\C4","ä":"\E4","Ö":"\D6","ö":"\F6","Ü":"\DC","ü":"\FC","ß":"\DF"} })'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
到
<text>Dies ist ein Test mit Umlauten: \E4, \F6, \FC, \DF, \C4, \D6, \DC.</text>
我意识到最后一个示例没有您描述的确切替换,但是当我尝试动态生成使用过的地图并且 运行 遇到 Saxon 生成正确语法以使用内部地图的问题对于 XSLT 属性,您需要将 map{"Ä":"\C4"
等值固定为 map{"Ä":"\'C4"
.
至于基于正则表达式的匹配和替换它们,在 XSLT 3.0 中使用 analyze-string
函数你可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:function name="mf:int-to-hex" as="xs:string">
<xsl:param name="int" as="xs:integer"/>
<xsl:sequence
select="if ($int eq 0)
then '0'
else concat(
if ($int gt 16)
then mf:int-to-hex($int idiv 16) else '',
substring('0123456789ABCDEF', ($int mod 16) + 1, 1)
)"/>
</xsl:function>
<xsl:template match="text()">
<xsl:value-of select="analyze-string(., '\p{IsLatin-1 Supplement}')/*/(if (. instance of element(fn:match)) then '\''' || mf:int-to-hex(string-to-codepoints(.)) else string())" separator=""/>
</xsl:template>
</xsl:stylesheet>