我使用MSXML 3.0和Visual Basic 6来存储和检索我的应用程序的配置。将生成的DOMDocument
保存到XML文件时,根对象将呈现为单个非常长的文本行:
<?xml version="1.0"?>
<!--WORKAPP 2011 Configuration file-->
<profile version="1.0"><frmPlan><left>300</left><top>300</top><width>24600</width><height>13575</height></frmPlan><preferences><text1/><text2/><text3/><background_color/><grid-major-step-x>50</grid-major-step-x><grid-major-step-y>50</grid-major-step-y></preferences></profile>
是否可以强制MSXML使用缩进和换行格式化生成的XML文件?
答案 0 :(得分:8)
对于像配置这样的小文件,使用XSL的开销可能并不重要。当您处理大型文件或大量小型文件(如Web服务器的服务器端)时,SAX的功能更为重要 - 您可能不应该首先使用重量级DOM。
Private Sub FormatDocToFile(ByVal Doc As MSXML2.DOMDocument, _
ByVal FileName As String)
'Reformats the DOMDocument "Doc" into an ADODB.Stream
'and writes it to the specified file.
'
'Note the UTF-8 output never gets a BOM. If we want one we
'have to write it here explicitly after opening the Stream.
Dim rdrDom As MSXML2.SAXXMLReader
Dim stmFormatted As ADODB.Stream
Dim wtrFormatted As MSXML2.MXXMLWriter
Set stmFormatted = New ADODB.Stream
With stmFormatted
.Open
.Type = adTypeBinary
Set wtrFormatted = New MSXML2.MXXMLWriter
With wtrFormatted
.omitXMLDeclaration = False
.standalone = True
.byteOrderMark = False 'If not set (even to False) then
'.encoding is ignored.
.encoding = "utf-8" 'Even if .byteOrderMark = True
'UTF-8 never gets a BOM.
.indent = True
.output = stmFormatted
Set rdrDom = New MSXML2.SAXXMLReader
With rdrDom
Set .contentHandler = wtrFormatted
Set .dtdHandler = wtrFormatted
Set .errorHandler = wtrFormatted
.putProperty "http://xml.org/sax/properties/lexical-handler", _
wtrFormatted
.putProperty "http://xml.org/sax/properties/declaration-handler", _
wtrFormatted
.parse Doc
End With
End With
.SaveToFile FileName
.Close
End With
End Sub
答案 1 :(得分:3)
这个答案可能对你的具体情况没有帮助,但总的来说它可能有用。它考虑了在没有太多修改的情况下加载和保存文档的情况。 DomDocument
具有preserveWhitespace
属性,最初设置为False
。如果您在True
之前将其设置为load
,则会使用与原始文件相同的缩进来保存它。
要手动添加缩进,可以创建文本节点并插入它们以在元素之间创建新的行和空格,如下所示:
Set txt = doc.createTextNode(vbCrLf & " ")
Call node.parentNode.insertBefore(txt, node)
答案 2 :(得分:2)
您可以查看this other question on SO以及答案的C ++代码。但是工作太多了。你说你只是存储一个配置文件。所以使用XSLT转换:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请记住输出到ADODB.Stream,而不是DOM。如果输出到DOM,则将忽略XSLT序列化程序。
答案 3 :(得分:1)
这是一个较短的缩进实用程序函数,它对DOM对象和字符串起作用作为输入并输出格式化字符串。文件处理(utf-8)不在其范围内。不使用ADODB流,在项目引用中不需要MSXML。
Public Function FormatXmlIndent(vDomOrString As Variant, sResult As String) As Boolean
Dim oWriter As Object ' MSXML2.MXXMLWriter
On Error GoTo QH
Set oWriter = CreateObject("MSXML2.MXXMLWriter")
oWriter.omitXMLDeclaration = True
oWriter.indent = True
With CreateObject("MSXML2.SAXXMLReader")
Set .contentHandler = oWriter
'--- keep CDATA elements
.putProperty "http://xml.org/sax/properties/lexical-handler", oWriter
.parse vDomOrString
End With
sResult = oWriter.output
'--- success
FormatXmlIndent = True
Exit Function
QH:
End Function
可以像这样使用
sXml = ReadTextFile("doc.xml")
FormatXmlIndent sXml, sXml
...所以如果有任何失败(无效的XML等),sXml
仍然保留原始未格式化的输入。