VBA 格式化輸出XML(UTF-8無BOM編碼)
VBA可以使用MSXML2.Document來建立XML Dom樹並輸出到檔案,先看個簡單的例子:
Function CreateXml(xmlFile As String)
Dim xDoc As Object
Dim rootNode As Object
Dim header As Object
Dim newNode As Object
Dim tNode As Object
Set xDoc = CreateObject("MSXML2.DOMDocument")
Set rootNode = xDoc.createElement("BookList" )
Set xDoc.DocumentElement = rootNode
'xDoc.Load xmlFile
Set header = xDoc.createProcessingInstruction("xml", "version='1.0' encoding='Unicode'")
xDoc.InsertBefore header, xDoc.ChildNodes(0)
Set newNode = xDoc.createElement("book")
Set tNode = xDoc.DocumentElement.appendChild(newNode)
tNode.setAttribute "type" , "program"
Set newNode = xDoc.createElement("name")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(0).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("Thinking in Java"))
Set newNode = xDoc.createElement("author")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(0).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("Bruce Eckel" ))
Set newNode = xDoc.createElement("book")
Set tNode = xDoc.DocumentElement.appendChild(newNode)
tNode.setAttribute "type", "literature"
Set newNode = xDoc.createElement("name")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(1).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("邊城"))
Set newNode = xDoc.createElement("author")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(1).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("沈從文"))
Set newNode = Nothing
Set tNode = Nothing
xDoc.save xmlFile
End Function
在巨集工程中呼叫一下這個函式工程,就可以生成一個xml檔案,但是生成的xml檔案所有內容都顯示在一行上了,有沒有方法進行換行及縮排,讓xml檔案看起來更整齊美觀呢?方法是有的,藉助Msxml2.SAXXMLReader和Msxml2.MXXMLWriter就可以實現這個效果,看程式碼:
'格式化xml,帶換行縮排
Function PrettyPrintXml(xmldoc) As String
Dim reader As Object
Dim writer As Object
Set reader = CreateObject("Msxml2.SAXXMLReader.6.0")
Set writer = CreateObject("Msxml2.MXXMLWriter.6.0")
writer.indent = True
writer.omitXMLDeclaration = True
reader.contentHandler = writer
reader.Parse (xmldoc)
PrettyPrintXml = writer.Output
End Function
然後將前面的xDoc.save xmlFile改一下:
'xDoc.save xmlFile
Dim xmlStr As String
xmlStr = PrettyPrintXml(xDoc)
WriteUtf8WithoutBom xmlFile, xmlStr
Open xmlFile For Output As #1
Print #1, xmlStr
Close #1
這樣就可以格式化輸出xml檔案了。還有一個問題,我們想要指定xml檔案的編碼格式,如UTF-8,GB2312等,我通常習慣儲存成UTF-8格式,那麼該如何設定呢?查詢資料,可以用ADODB.stream來搞。
Function WriteWithUtf8(filename As String, content As String)
Dim stream As New ADODB.stream
stream.Open
stream.Type = adTypeText
stream.Charset = "utf-8"
stream.WriteText content
stream.SaveToFile filename, adSaveCreateOverWrite
stream.Flush
stream.Close
End Function
細心點的話會發現用上面的方法實際上輸出的檔案格式是帶BOM的UTF-8,它跟UTF-8無BOM的區別在哪呢?用UltraEdit工具來看十六進位制碼,會發現前者在開頭多了三個位元組:0xEF,0xBB,0xBF,想儲存成UTF-8無BOM,把這三個位元組去掉不就行了,實現如下:
' utf8無BOM編碼格式
Function WriteUtf8WithoutBom(filename As String, content As String)
Dim stream As New ADODB.stream
stream.Open
stream.Type = adTypeText
stream.Charset = "utf-8"
stream.WriteText "<?xml version=" & Chr(34) & "1.0" & Chr(34) & _
" encoding=" & Chr(34) & "UTF-8" & Chr(34) & "?>" & vbCrLf
stream.WriteText content
'移除前三個位元組(0xEF,0xBB,0xBF)
stream.Position = 3
Dim newStream As New ADODB.stream
newStream.Type = adTypeBinary
newStream.Mode = adModeReadWrite
newStream.Open
stream.CopyTo newStream
stream.Flush
stream.Close
newStream.SaveToFile filename, adSaveCreateOverWrite
newStream.Flush
newStream.Close
End Function
注意需要引用兩個庫:Microsoft ADO Ext. 6.0 for DDL and Security,Microsoft ActiveX Data Objects 2.7 Library
最後附上完整程式碼:
Sub 按鈕2_Click()
Dim xmlFile As String
xmlFile = "D:\test\books.xml"
CreateXml xmlFile
End Sub
Function CreateXml(xmlFile As String)
Dim xDoc As Object
Dim rootNode As Object
Dim header As Object
Dim newNode As Object
Dim tNode As Object
Set xDoc = CreateObject("MSXML2.DOMDocument")
Set rootNode = xDoc.createElement("BookList")
Set xDoc.DocumentElement = rootNode
'xDoc.Load xmlFile
Set header = xDoc.createProcessingInstruction("xml", "version='1.0' encoding='Unicode'")
xDoc.InsertBefore header, xDoc.ChildNodes(0)
Set newNode = xDoc.createElement("book")
Set tNode = xDoc.DocumentElement.appendChild(newNode)
tNode.setAttribute "type", "program"
Set newNode = xDoc.createElement("name")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(0).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("Thinking in Java"))
Set newNode = xDoc.createElement("author")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(0).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("Bruce Eckel"))
Set newNode = xDoc.createElement("book")
Set tNode = xDoc.DocumentElement.appendChild(newNode)
tNode.setAttribute "type", "literature"
Set newNode = xDoc.createElement("name")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(1).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("邊城"))
Set newNode = xDoc.createElement("author")
Set tNode = xDoc.DocumentElement.ChildNodes.Item(1).appendChild(newNode)
tNode.appendChild (xDoc.createTextNode("沈從文"))
Set newNode = Nothing
Set tNode = Nothing
Dim xmlStr As String
xmlStr = PrettyPrintXml(xDoc)
WriteUtf8WithoutBom xmlFile, xmlStr
Set rootNode = Nothing
Set xDoc = Nothing
MsgBox xmlFile & "輸出完成"
End Function
'格式化xml,帶換行縮排
Function PrettyPrintXml(xmldoc) As String
Dim reader As Object
Dim writer As Object
Set reader = CreateObject("Msxml2.SAXXMLReader.6.0")
Set writer = CreateObject("Msxml2.MXXMLWriter.6.0")
writer.indent = True
writer.omitXMLDeclaration = True
reader.contentHandler = writer
reader.Parse (xmldoc)
PrettyPrintXml = writer.Output
End Function
' utf8無BOM編碼格式
Function WriteUtf8WithoutBom(filename As String, content As String)
Dim stream As New ADODB.stream
stream.Open
stream.Type = adTypeText
stream.Charset = "utf-8"
stream.WriteText "<?xml version=" & Chr(34) & "1.0" & Chr(34) & _
" encoding=" & Chr(34) & "UTF-8" & Chr(34) & "?>" & vbCrLf
stream.WriteText content
'移除前三個位元組(0xEF,0xBB,0xBF)
stream.Position = 3
Dim newStream As New ADODB.stream
newStream.Type = adTypeBinary
newStream.Mode = adModeReadWrite
newStream.Open
stream.CopyTo newStream
stream.Flush
stream.Close
newStream.SaveToFile filename, adSaveCreateOverWrite
newStream.Flush
newStream.Close
End Function
相關推薦
VBA 格式化輸出XML(UTF-8無BOM編碼)
VBA可以使用MSXML2.Document來建立XML Dom樹並輸出到檔案,先看個簡單的例子: Function CreateXml(xmlFile As String) Dim xDoc As Object Dim rootNode As
讀取xml格式utf-8編碼 和utf-8 無bom編碼格式,出現 前言中不允許有內容的問題
1,java 讀取 xml utf-8 編碼格式的檔案,出現 Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允許有內容。 出現這樣的原因, 是因為讀取檔案
utf-8無BOM編碼格式什麼意思?
UTF-8不需要BOM來表明位元組順序,但可以用BOM來表明編碼方式。字元"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF。所以如果接收者收到以EF BB BF開頭的位元組流,就知道這是UTF-8編碼了。 ---------------
C#使用StreamWriter生成UTF-8無BOM編碼格式
使用UTF-8格式產生的檔案,用二進位制檢視會多出“\xef\xbb\xbf”幾個位元組 使用UTF-8無BOM格式: UTF8Encodingutf8 = new UTF8Encoding(fal
UTF-8和UTF-8無BOM,一個會導致文件中中文變量無法匹配的bug
阿裏旺旺 bsp bom logs 文件 匹配 文件的 程序 資料 昨晚用dom4j中的selectSingleNode解析xml,匹配節點。 發現匹配不到,但是確實存在該節點 將regex改為regex1後則可以匹配,也就是說文件中的“阿裏旺旺”和程序中的“阿裏旺旺
Visual Studio 2017 UTF-8 無 BOM 一站式解決辦法
exe end pre utf8 space spa code ets mic 問題背景:最近撿起C++,使用VS 2017平臺。因為以前的編程習慣,喜歡使用UTF-8 無 BOM 的編碼格式,好讓自己的代碼全球通用。但是VS 2017 對這個問題不是很友善。但最終找到了解
VS 修改預設編碼格式 為utf-8 無 BOM 與 utf-8 帶BOM
VS 在使用的時候預設的編碼格式為 GB2312 如何修改預設的編碼格式呢? 網上都說修改 VS 建立檔案時的模板 如C++ 則修改 C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcprojectitems
因字符集utf-8無BOM格式編碼,導致用sql檔案匯入MySQL出現亂碼問題
在使用.sql檔案向MySQL資料庫插入時,部分中文字元出現亂碼,不能匯入,比如說“交通”、“釀”、“制”等。 sql語句: INSERT INTO `course` VALUES (1,'交通',901); 報錯:You have an error in your S
vs2015:/utf-8選項解決UTF-8 without BOM 原始碼中文輸出亂碼問題
本來我已經參考網上關於C++中文輸出亂碼的文章解決了,如下面的程式碼輸出前呼叫wcout.imbue設定locale,就可以正常輸出中文了。 std::wcout.imbue(std::locale(std::locale(), "", LC_CTYPE)
編碼格式簡介:ASCII碼、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM頭
family 用兩個 圖片 and 正是 全球化 asc 即使 little 編碼格式簡介:ASCII碼、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM頭 二進制: 只有0和1。 十進制、十六進制、八進制: 計算機其實挺笨的,它只
去掉utf-8的Bom頭:使用java以及jdbc不使用第三方庫執行sql文件腳本
語句 \n path expect continue 參數 oid while figure package com.xxx.xxx.dao; import java.io.BufferedReader; import java.io.File; import java
關於Encode in UTF-8 without BOM
什麽 nic 代碼 網頁代碼 使用 python 文件頭部 環境 解釋 定義BOM(Byte Order Mark),字節順序標記,出現在文本文件頭部,Unicode編碼標準中用於標識文件是采用哪種格式的編碼。它的編碼是FEFF。 說明 在 UTF-8 文件中放置 BOM
MySQL修改編碼為UTF-8無效果解決辦法
本來這是一件很簡單的事,有很多部落格裡都有教程,但卻足足花了我半天的時間才解決問題。 可能是因為我的MySQL安裝時沒有選擇預設路徑的原因,按照網上的教程修改了下圖中的my.ini配置檔案後編碼並沒有發生變化。 來回試了好幾次都不行,重啟了服務N次..... [mysqld] characte
UTF-8 without BOM
UTF-8編碼的檔案可以分為without BOM和BOM兩種格式。 何謂BOM? "EF BB BF" 這三個位元組就叫BOM,BOM的全稱叫做"Byte Order Mark". 在UTF-8檔案中常用BOM來表明這個檔案是UTF-8檔案, 而BOM的本意是在UTF-16中用來表示高低位元組序列
UTF-8與UTF-8 without BOM
UTF-8編碼的檔案可以分為without BOM和BOM兩種格式。 何謂BOM? “EF BB BF” 這三個位元組就叫BOM,BOM的全稱叫做"Byte Order Mark". 在UTF-8檔案中常用BOM來表明這個檔案是UTF-8檔案, 而BOM的本意是
lua去掉字串中的UTF-8的BOM三個位元組
今天被坑了,原因是在lua中解析csv時,由於csv使用的是UTF-8 BOM格式,所以在解析csv成lua表時,表頭ID欄位,明明你列印的時候在表中存在,但是你去訪問v[‘ID’]的時候,始終為nil。原因就是ID是csv表的開頭欄位字串,BOM格式會預設增加三個不可見的位元組 0xE
Python學習筆記:Convert UTF-8 with BOM to UTF-8 without BOM in Python
前言 windows對於utf-8編碼的檔案自帶BOM,但是其他系統utf-8編碼預設不帶BOM。 這就造成在某些情況下字元解碼會出現問題,比如python自帶的json在讀取在window下編碼得來的utf-8檔案時,會報如下錯誤: V
[經驗總結]利用MFC的CFile物件輸出utf-8和ansi編碼的文字
// 今天寫了一段輸出文字到檔案的程式碼,一開始用CFile輸出中文,總是出現亂碼,又是百度(Google被牆了)一番,網上的教程基本是隻知其一不知其二,大多隻講了輸出檔案位元組序標記和計算寬字元長度這兩個注意點,卻沒有提到字元轉換這個最關鍵的一步。下面的程式碼分別輸出UTF-8和ANSI(簡體中文Windo
使用dom4j 生成xml UTF-8 編碼錯誤之解決
//檔名稱 String fileName = "test.xml"; // 格式化XML文件 OutputFormat format = OutputFormat.createPrettyPrint(); format.setE
C# UTF-8 去BOM頭
在C#中,當使用帶有BOM頭的UTF-8編碼的字串時,一定要注意。 1)如果該字串用作路徑,用來定址。一定會出錯。2)轉換格式時,也很容易出錯。例如字串轉int就一定會出錯。 待續… ——————————————————————————————————————