Я пытаюсь обработать XML-файл, который утверждает (правильно я верю), что он закодирован в 7-битном ASCII, но он содержит текстовые значения, которые включают в себя символьные объекты, такие как ×
, которые преобразуются в символы Юникода.
Проблема заключается (я думаю) в том, что процессор (версия Xalan в комплекте с Treebeard) разрешает символьные объекты и превращает их в 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 °F</name>
<printSymbol>Btu<sub>39°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='"×"' />
<xsl:variable name="crlf" select='" "' />
<xsl:variable name="lf" select='" "' />
<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>
Вывод - обратите внимание, что символы степени (для градуса F) искажены
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.
Идеи или ссылки на ответы очень ценятся.
- ОБНОВЛЕНИЕ - Мое первоначальное предположение было неверным.Некоторые эксперименты с другими форматами вывода показывают, что (например) с методом вывода, установленным на HTML, проблемные символы выводятся как объекты HTML.Это указывает на то, что символы являются , что превращает его в перевод без изменений.Я предполагаю, что это должна быть обработка вывода, вызывающая проблему.
В соответствии с просьбой я взял небольшой фрагмент текста (часть элемента имени «при 39 ° F») и выгрузил шестнадцатеричный код вводаи выходные строки.
![hex analysis of a piece of the text](https://i.stack.imgur.com/5T1ri.png)
- ОБНОВЛЕНИЕ - Некоторые раскопки показали, что -
- Оригинальный инструмент (Древобородый)преобразовывал вывод в UTF-8, но затем: (а) отображал его неправильно (я думаю, что cp1252);(b) Преобразование вывода в cp1252 при записи вывода в файл.
- Второй инструмент (Простое преобразование XSLT) правильно отображал вывод utf8 на экране, но все же преобразовывался в cp1252 при записи на диск.
- A thread на этом сайте подтвердил, что Java запускает кодировку файла по умолчанию при запуске.Поскольку оба инструмента написаны на Java, это вызывало проблему с выводом файла.
Я следовал рекомендации в этом потоке, чтобы настроить переменную среды Windows следующим образом: JAVA_TOOL_OPTIONS = Dfile.encoding=UTF8
Успех!
Файл записан в utf8 и может быть успешно открыт в Notepad ++ или Excel (PowerQuery).Вы должны вручную установить кодовую страницу «cp65001» в PowerQuery, но она работает.
Спасибо тем, кто ответил, вы помогли мне встать на правильный путь.