打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
VBA 格式化输出XML(UTF

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 xmlFileEnd Function
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

在宏工程中调用一下这个函数工程,就可以生成一个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.OutputEnd Function
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

然后将前面的xDoc.save xmlFile改一下:

'xDoc.save xmlFileDim xmlStr As StringxmlStr = PrettyPrintXml(xDoc)WriteUtf8WithoutBom xmlFile, xmlStrOpen xmlFile For Output As #1Print #1, xmlStrClose #1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这样就可以格式化输出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.CloseEnd Function
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

细心点的话会发现用上面的方法实际上输出的文件格式是带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.CloseEnd Function
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

注意需要引用两个库: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 xmlFileEnd SubFunction 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.OutputEnd 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
XMLHTTP资料
VB.Net创建XML文件的方法
js DOM节点的创建、插入、删除、查找、替换例子
XmlNode与XmlElement
VBA宏,可以用Excel来生成XML文件
document.createElement()的用法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服