0

我正在尝试处理一个声称(我相信正确)以 7 位 ASCII 本身编码的 XML 文件,但它包含的文本值包含×解析为 Unicode 字符的字符实体。

问题是(我认为)处理器(与 Treebeard 捆绑在一起的 Xalan 版本)正在解析字符实体并将它们变成 gobbledegook,甚至在 XSLT 样式表接触到内容之前。

我在下面整理了一个精简的测试用例-

XML 输入数据

<?xml version="1.0" encoding="ascii"?>
<root>
   <unit Code="[Btu_39]" CODE="[BTU_39]" isMetric="no" class="heat">
      <name>British thermal unit at 39&#160;&#176;F</name>
      <printSymbol>Btu<sub>39&#176;F</sub>
      </printSymbol>
      <property>energy</property>
      <value Unit="kJ" UNIT="kJ" value="1.05967">1.05967</value>
   </unit>
</root>

XSLT 样式表

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="utf-8" />

    <xsl:variable name="sep" select='";"' />
    <xsl:variable name="mult" select='"&#215;"' />
    <xsl:variable name="crlf" select='"&#13;&#10;"' />
    <xsl:variable name="lf" select='"&#10;"' />

    <xsl:strip-space elements="name printSymbol value" />

    <xsl:template match="/root">
        <xsl:apply-templates select="*" />
    </xsl:template>

    <xsl:template match="/root/*">
        Type: <xsl:value-of select="name()" />
        Code: <xsl:value-of select="@Code" />
        CODE: <xsl:value-of select="@CODE" />
        Description: <xsl:apply-templates select="name" />
        Print: <xsl:apply-templates select="printSymbol" />
        Property: <xsl:apply-templates select="property" />
        Value: <xsl:apply-templates select="value" />
        <xsl:value-of select="$lf" />       
    </xsl:template>

    <xsl:template match="name|printSymbol|property">
        <xsl:value-of select="text()" />
    </xsl:template>

    <xsl:template match="value">
        <xsl:value-of select="concat(@value, $mult, @Unit, $lf)" />
    </xsl:template>

</xsl:stylesheet>

输出 - 注意度数符号(对于华氏度)被破坏

Type: unit
Code: [Btu_39]
CODE: [BTU_39]
Description: British thermal unit at 39 °F
Print: Btu
Property: energy
Value: 1.05967×kJ

我在编程部分发现了与此类似的问题,一个答案是预处理输入文件以转义或编码字符实体,但在这种情况下,我使用 XSLT“裸”而不涉及其他语言,所以我真的需要一个纯 XSLT 解决方案。

非常感谢答案的想法或链接。

--UPDATE-- 我最初的猜测是错误的。对其他输出格式的一些试验表明(例如)将输出方法设置为 HTML 时,问题字符将作为 HTML 实体输出。这表明字符正在将其转换为未损坏的翻译。我认为它一定是导致问题的输出处理。

根据要求,我取了一小块文本(名称元素的“39°F”部分)并转储了输入和输出字符串的十六进制。

一段文本的十六进制分析

--更新--一些挖掘表明-

  1. 原始工具 (Treebeard) 将输出转换为 UTF-8,但随后: (a) 显示不正确(我认为是 cp1252);(b) 将输出写入文件时将输出转换为 cp1252。
  2. 第二个工具(简单 XSLT 转换)在屏幕上正确显示 utf8 输出,但在写入磁盘时仍转换为 cp1252。
  3. 该站点上的一个线程确认 Java 在启动时采用了默认文件编码。由于这两个工具都是用 Java 编写的,这导致了文件输出问题。

我按照该线程中的建议设置了一个 Windows 环境变量,如下所示:JAVA_TOOL_OPTIONS = Dfile.encoding=UTF8

成功!

该文件被写入 utf8 并且可以在 Notepad++ 或 Excel (PowerQuery) 中成功打开。您必须在 PowerQuery 中手动设置“cp65001”代码页,但它可以工作。

感谢那些回答的人,你帮助我走上了正轨。

4

0 回答 0