MSXMLWriter60 не выводит byteOrderMark для кодировки UTF-16

Я использую вариант кода, показанный в "Как включить XMLDOMDocument XML-декларацию?" (которую также можно увидеть по адресу MSDN. Если я изменю кодировку на "UTF-16", можно подумать, что она будет выводиться как UTF-16... и она "делает"... глядя на вывод в тексте редакторе; но проверяя его в шестнадцатеричном редакторе, метка порядка байтов отсутствует (несмотря на то, что свойство имеет значение true), а редакторы XML отклоняют документ как недействительный UTF-16 из-за отсутствующей спецификации.

Что я упускаю из виду?

'' # Create and load a DOMDocument object.

Dim xmlDoc As New DOMDocument60
xmlDoc.loadXML("<doc><one>test1</one><two>test2</two></doc>")

'' # Set properties on the XML writer - including BOM, XML declaration and encoding

Dim wrt As New MXXMLWriter60
wrt.byteOrderMark = True
wrt.omitXMLDeclaration = False
wrt.encoding = "UTF-16"
wrt.indent = False

'' # Set the XML writer to the SAX content handler.

Dim rdr As New SAXXMLReader60
Set rdr.contentHandler = wrt
Set rdr.dtdHandler = wrt
Set rdr.errorHandler = wrt
rdr.putProperty "http://xml.org/sax/properties/lexical-handler", wrt
rdr.putProperty "http://xml.org/sax/properties/declaration-handler", wrt

'' # Now pass the DOM through the SAX handler, and it will call the writer

rdr.parse xmlDoc

'' # Let the writer do its thing

Dim iFileNo As Integer
iFileNo = FreeFile
Open App.Path + "\saved.xml" For Output As #iFileNo
Print #iFileNo, wrt.output
Close #iFileNo

Вывод выглядит так:

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<doc><one>test1</one><two>test2</two></doc>

Почему я использую VB6? На самом деле это VBA (то же поколение, небольшое подмножество VB6), который используется в качестве языка сценариев для InputAccel/FormWare EMC-Captiva, поэтому переключение не вариант.


person Michael Paulukonis    schedule 08.12.2009    source источник


Ответы (1)


Проблема в том, что когда вы извлекаете значение из выходного свойства модуля записи, вы получаете строку. Поскольку строки в VB всегда UTF-16, это то, что вы получаете независимо от кодировки. Поскольку строки в VB всегда имеют кодировку UTF-16, нет понятия, что им нужна спецификация, поэтому она также не включена.

Свойства кодировки и спецификации влияют только на то, как модуль записи будет записывать XML, если реализация IStream назначена выходному свойству.

Попробуйте изменить код вокруг вызова для синтаксического анализа следующим образом:

Dim oStream As ADODB.Stream
Set oStream =  New ADODB.Stream
oStream.Open
oStream.Type = adTypeBinary

wrt.output = oStream

rdr.parse xmlDoc

oStream.SaveToFile App.Path + "\saved.xml"
oStream.Close

Это должно привести к желаемому результату.

person AnthonyWJones    schedule 08.12.2009
comment
Подтверждено, я получил тот же результат другим способом. Важно установить выходное свойство сначала перед другими свойствами, иначе вы все равно не получите спецификацию. - person Hans Passant; 08.12.2009
comment
@nobugz: Да, хороший улов, назначение выходного свойства должно произойти до назначения других свойств. - person AnthonyWJones; 08.12.2009
comment
oStream.Type = adTypeBinary в моем VBA, но это помогло. Спасибо! - person Michael Paulukonis; 08.12.2009
comment
@OtherMichael: Соответственно изменил мой код, я признаю, что догадался об этой константе, у меня не установлен VB6 на машине, которую я сейчас использую, я тестировал в VBScript. - person AnthonyWJones; 08.12.2009