Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用XSLT1.0将UTF8 4位表示转换回原始字符集?_Xslt_Oracle11g - Fatal编程技术网

如何使用XSLT1.0将UTF8 4位表示转换回原始字符集?

如何使用XSLT1.0将UTF8 4位表示转换回原始字符集?,xslt,oracle11g,Xslt,Oracle11g,我正在为Oracle编写一个PL/SQL工具,以便从游标中获取XML电子表格 几天后,我得出结论,完成这项工作最简单的方法就是利用OracleDB提供的XML特性 因此,我的想法是将查询结果格式化为XML,然后通过XSLT获得Excel电子表格 到目前为止,一切顺利:我成功地从我编写的查询中获得了电子表格,但我需要解决一个小问题 我希望能够在Excel中设置列标题,只是在列上设置别名,但是当我使用与XML语言不兼容的字符时,我显然得到了与我的意思不同的东西 select dbms_xmlgen.

我正在为Oracle编写一个PL/SQL工具,以便从游标中获取XML电子表格

几天后,我得出结论,完成这项工作最简单的方法就是利用OracleDB提供的XML特性

因此,我的想法是将查询结果格式化为XML,然后通过XSLT获得Excel电子表格

到目前为止,一切顺利:我成功地从我编写的查询中获得了电子表格,但我需要解决一个小问题

我希望能够在Excel中设置列标题,只是在列上设置别名,但是当我使用与XML语言不兼容的字符时,我显然得到了与我的意思不同的东西

select dbms_xmlgen.getxmltype(
'select first_name as "First na/Me" 
   from hr.employees
  where department_id = 100;') from dual;
生成:

<ROWSET>
 <ROW>
  <First_x0020_na_x002F_Me>Nancy</First_x0020_na_x002F_Me>
 </ROW>
<ROWSET>

南希
但是,没有什么可以阻止我获取Excel,然后通过XSLT将上面的XML文档转换为包含此节点的Excel 2007兼容工作簿

<Cell>
 <Data ss:Type="String">First_x0020_na_x002F_Me</Data>
</Cell>

首先是我
此时,我只需要指示XSLT ti在列标题中搜索“x\uFFFF”,提取十六进制代码并将其转换为相应的字符,但如何才能做到这一点

正如标题中提到的,我的XSLT是1.0兼容的,但如果需要,我可以升级到更高版本,并且由于Oracle DB中对XSLT 2.0的本机支持不受支持,因此无法升级

此时,我只需要指示XSLT在列中搜索 “x\uFFFF”的标题,提取十六进制代码并将其转换为 对应的字符,但如何才能做到这一点

正如标题中所提到的,我的XSLT是1.0兼容的,但是我可以升级 如有必要,可升级至更高版本

此XSLT 2.0转换

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()[matches(., '_x(\d|[A-Fa-f]){4}_')]">
    <xsl:analyze-string select="." regex="_x((\d|[A-Fa-f]){{4}})_" >
      <xsl:matching-substring>
        <xsl:value-of select="codepoints-to-string(my:hex-to-int(regex-group(1), 0))"/>
      </xsl:matching-substring>
      <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:template>

  <xsl:function name="my:hex-to-int" as="xs:integer">
    <xsl:param name="pHex" as="xs:string"/>
    <xsl:param name="pResult" as="xs:integer"/>

    <xsl:sequence select=
    "if(not($pHex))
       then $pResult
       else
         my:hex-to-int(substring($pHex, 2), 
                       16*$pResult + my:hex-digit-to-int(substring($pHex, 1, 1)))
    "/>
  </xsl:function>

  <xsl:function name="my:hex-digit-to-int" as="xs:integer">
    <xsl:param name="pHexDigit" as="xs:string"/>

    <xsl:sequence select=
       "index-of(string-to-codepoints('0123456789abcdef'), 
                 string-to-codepoints(lower-case($pHexDigit)))[1] -1"/>
  </xsl:function>
</xsl:stylesheet>
<Cell xmlns:ss="some:ss">
    <Data ss:Type="String">First_x0020_na_x002F_Me</Data>
</Cell>
<Cell xmlns:ss="some:ss">
      <Data ss:Type="String">First na/Me</Data>
</Cell>



应确保正确表示不安全字符。

“我的XSLT兼容1.0,但可以升级”我相信您会更乐于使用XSLT 2.0,它支持
codepoints-to-string()
函数(以及其他使字符串处理更容易的函数)。我将查看一下,看看是否可以完成这些工作。@Max我应该补充一点,这可以在XSLT 1.0中完成-前提是您有一个可能需要恢复的有限字符列表。但是如果没有regex支持的好处,仍然会很尴尬。很不幸,我刚刚发现oracle11gr2在内部不支持xslt2.0。包装Java XSLT 2.0处理器是可能的,但我希望只使用Oracle本机特性就可以完成这些工作。因此,我需要研究另一种方法。@Max,然后您需要添加一个书面扩展函数,该函数接受一个整数并将其用作Unicode代码值,以返回与该值对应的字符——基本上与标准XPath 2.0函数
codepoints-to-string()
所做的操作相同。如果您可以创建此扩展函数,那么我将向您介绍XSLT 1.0转换的其余部分。这将非常好,但不幸的是,我发现Oracle本机不支持XSLT 2.0,因此我无法依赖您的出色解决方案。此外,我刚刚意识到我最初的要求是不正确的:如果字符串中出现“@Max,我很乐意在将来帮助您,只要您进一步开发了您的要求。@Max,Re:“如果字符串中出现一个”
<xsl:output method="html"/>
<xsl:output method="xhtml"/>