【问题标题】:MSXMLWriter60 doesn't output byteOrderMark for UTF-16 encodingMSXMLWriter60 不为 UTF-16 编码输出 byteOrderMark
【发布时间】:2010-12-24 12:46:18
【问题描述】:

我正在使用"How to make XMLDOMDocument include the XML Declaration?" 中看到的代码变体(也可以在MSDN 看到。如果我将编码更改为“UTF-16”,人们会认为它会输出为 UTF-16.. . 并且它“确实”...通过在文本编辑器中查看输出;但是在十六进制编辑器中检查它,字节顺序标记丢失(尽管属性设置为 true),并且 XML 编辑器拒绝该文档作为无效的 UTF-16,对于缺少的 BOM。

我忽略了什么?

'' # 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 的小子集)中,用作 EMC-Captiva 的 InputAccel/FormWare 的脚本语言,因此不能切换。

【问题讨论】:

    标签: xml vba vb6 utf-16 byte-order-mark


    【解决方案1】:

    问题在于,当您从编写器的输出属性中检索一个值时,您会得到一个字符串。由于 VB 中的字符串始终是 UTF-16,所以无论编码如何,您都可以得到。由于字符串在 VB 中始终为 UTF-16,因此不存在它们需要 BOM 的概念,因此也不包括在内。

    编码和 BOM 属性仅在将 IStream 的实现分配到输出属性时影响编写器写入 XML 的方式。

    尝试围绕调用修改代码以进行如下解析:-

    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
    

    这应该会生成所需的输出。

    【讨论】:

    • 确认,我通过另一种方式得到了相同的结果。在其他属性之前设置输出属性 first 很重要,否则您仍然无法获得 BOM。
    • @nobugz:是的,很好,分配给输出属性需要在分配其他属性之前发生。
    • "oStream.Type = adTypeBinary" 在我的 VBA 中,但这成功了。谢谢!
    • @OtherMichael:相应地调整了我的代码,我承认我猜到了那个常数,我没有在我目前使用的机器上安装 VB6,我在 VBScript 中进行了测试。
    猜你喜欢
    • 2012-03-16
    • 2012-03-13
    • 2019-05-23
    • 2016-01-02
    • 2012-06-30
    • 1970-01-01
    • 2012-06-20
    • 2011-08-18
    • 1970-01-01
    相关资源
    最近更新 更多