VBA与XSLT配合使用,可以在同一行中漂亮地打印带有结束标记的XML


<Root ID="123"   Name="Board">
<Element1 name="AAA"/>
<Element2 name="BBB"/>
<Element3 name="CCC"/>
<Element4 name="DDD" Age="56" Address="78"/>
<Nested_Elements>
<Nested Number="125"/>
<Nested Number="250"/>
<Nested Number="500"/>
<Nested Number="1000"/>
</Nested_Elements>
</Root>

我写了VBA代码来导出XML,并使用XSLT样式通过添加这个来漂亮地打印它

Set xslDoc = New MSXML2.DOMDocument
xslDoc.LoadXML "<?xml version=" & Chr(34) & "1.0" & Chr(34) & "?>" _
& "<xsl:stylesheet version=" & Chr(34) & "1.0" & Chr(34) _
& "                xmlns:xsl=" & Chr(34) & "http://www.w3.org/1999/XSL/Transform" & Chr(34) & ">" _
& "  <xsl:strip-space elements=" & Chr(34) & "*" & Chr(34) & " />" _
& "  <xsl:output method=" & Chr(34) & "xml" & Chr(34) & " indent=" & Chr(34) & "yes" & Chr(34) & "" _
& "            encoding=" & Chr(34) & "UTF-8" & Chr(34) & "/>" _
& "  <xsl:template match=" & Chr(34) & "node() | @*" & Chr(34) & ">" _
& "    <xsl:copy>" _
& "       <xsl:apply-templates select=" & Chr(34) & "node() | @*" & Chr(34) & " />" _
& "    </xsl:copy>" _
& "  </xsl:template>" _
& "</xsl:stylesheet>"
xslDoc.async = False
Set XmlNewDoc = New MSXML2.DOMDocument
XDoc.transformNodeToObject xslDoc, XmlNewDoc   'Line to fix indention
XmlNewDoc.Save XmlFile

问题是,这将添加额外的结束标签,如

<Root ID="123"   Name="Board">
<Element1 name="AAA">
</Element1>
<Element2 name="BBB">
</Element2>
<Element3 name="CCC">
</Element3>
<Element4 name="DDD" Age="56" Address="78">
</Element4>
<Nested_Elements>
<Nested Number="125">
</Nested>
<Nested Number="250">
</Nested>
<Nested Number="500">
</Nested>
<Nested Number="1000">
</Nested>
</Nested_Elements>

我知道它应该与XML观点没有任何区别,但我需要这些文件具有与旧文件相同的结构,以解决配置管理问题,

知道如何改变它以产生相同的结束标签吗?

如果MSXML版本呈现了不需要的结束标记,请考虑另一种XSLT1.0处理器。NET的XslCompiledTransform是大多数Windows机器附带的一个免费版本。

这个类可以通过Powershell脚本访问和运行,Powershell脚本可以在命令行运行,也可以通过Excel使用Shell命令运行。此XSLT版本将呈现自关闭标记。

输入 (另存为Input.xml(

<Root ID="123"   Name="Board">
<Element1 name="AAA">
</Element1>
<Element2 name="BBB">
</Element2>
<Element3 name="CCC">
</Element3>
<Element4 name="DDD" Age="56" Address="78">
</Element4>
<Nested_Elements>
<Nested Number="125">
</Nested>
<Nested Number="250">
</Nested>
<Nested Number="500">
</Nested>
<Nested Number="1000">
</Nested>
</Nested_Elements>
</Root>

XSLT(另存为style.xsl(

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

Powershell(另存为run_xslt.ps1文件(

# Load the style sheet.
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load("C:PathTostyle.xsl");
# Execute the transform and output the results to a file.
$xslt.Transform("C:PathToinput.xml", "C:PathTooutput.xml");

VBA(蓝色屏幕应弹出任何错误或输出消息(

Sub RunXSLT()
Dim RetVal As Variant

RetVal = Shell("Powershell.exe -ExecutionPolicy Bypass -noexit -File " & _
"""C:PathTorun_xslt.ps1""", 1)
End Sub

输出(Output.xml(

<?xml version="1.0" encoding="utf-8"?>
<Root ID="123" Name="Board">
<Element1 name="AAA" />
<Element2 name="BBB" />
<Element3 name="CCC" />
<Element4 name="DDD" Age="56" Address="78" />
<Nested_Elements>
<Nested Number="125" />
<Nested Number="250" />
<Nested Number="500" />
<Nested Number="1000" />
</Nested_Elements>
</Root>

在与XSLT进行斗争以删除此处的名称空间之后,如何忽略XML名称空间,我设法对输出进行了prettyPrint,但仍然得到了那些烦人的空标记<tag></tag>,所以我仍然依赖于我使用的初始函数,它适用于任何面临相同问题的人(您只需要添加对Microsoft XML, v6.0的引用(:

Public Function PrettyPrintXML(XML As String) As String
Dim Reader As New SAXXMLReader60, Writer As New MXXMLWriter60
Writer.indent = True: Writer.standalone = False
Writer.omitXMLDeclaration = True: Writer.Encoding = "utf-8"
Set Reader.contentHandler = Writer: Set Reader.dtdHandler = Writer: Set Reader.errorHandler = Writer
Call Reader.putProperty("http://xml.org/sax/properties/declaration-handler", Writer)
Call Reader.putProperty("http://xml.org/sax/properties/lexical-handler", Writer)
Call Reader.parse(XML) 'A document must contain exactly one root element
PrettyPrintXML = Writer.output
End Function

这将处理缩进和自关闭<tags />,与@Parfait在VBA中使用DOM创建XML的其他解决方案不同,后者可以prettyPrint XML,但不能解决关闭标记的问题。

最新更新