Excel XML导入会为空值创build一个名为NULL的额外列

我正在使用带有DOMDocument60parsing器的Excel 2010 / VBA / XML在Oracle中生成数据报告。 我有一个空值的问题。 Oracle在xsql查询中支持null-indicator="yes" ,以确保返回的logging集中包含空字段。 如果一个字段有一个值,那么XML看起来像这样: <M_NOTCH>8</M_NOTCH> ,如果它是空的,它看起来像这样: <M_NOTCH NULL="TRUE"/>

我的代码调用Web服务进行查询:

 Dim XML_HTTP As New MSXML2.XMLHTTP60: Call XML_HTTP.Open("POST", QUERY_URL, False): Call XML_HTTP.send 

并检索XML结果:

 Dim XML_OUTPUT As DOMDocument60: Set XML_OUTPUT = XML_HTTP.responseXML 

它保存文件:

 XML_OUTPUT.Save (FILE_PATH) 

然后从保存的文件中加载电子表格:

 Call DestinationWorksheet.Parent.XmlImport(FILE_PATH, Nothing, True, DestinationWorksheet.Range("A1")) 

它使用XML数据填充Excel电子表格。

如果<M_NOTCH NULL="TRUE"/>格式为空,Excel会认为这是两个字段,并为M_NOTCH(此行没有数据)创build一列,另一个列为NULL,值为TRUE 。

我曾尝试使用xsql设置null-indicator =“no”,这消除了NULL列,但它有一个不同的,不可接受的问题:dynamic构build的列顺序,以便如果第一个XMLlogging代表一个Oraclelogging如果空值字段从XML中排除,并且只有在包含这些字段的logging遇到时才被添加到Excel列表列表中,在这种情况下,它们被添加到列列表的末尾。

我也尝试用<M_NOTCH NULL="TRUE"/> <M_NOTCH> </M_NOTCH>replace<M_NOTCH NULL="TRUE"/> <M_NOTCH> </M_NOTCH> ,这是成功的。

有谁知道如何让Oracle使用语法<M_NOTCH> </M_NOTCH>或让Excel识别<M_NOTCH NULL="TRUE"/>并且不要添加额外的列?

考虑一个XSLT (声明式编程语言,为了最终用途需要重新构造XML文件)去除@NULL属性。 VBA可以使用带有Microsoft XML对象的XSLT处理器。 所需的XSLT非常简单直接,您可以在其中包含标识转换以便按原样复制所有内容(节点和属性),然后在@NULL上运行空白模板匹配以删除文档中出现的任何位置。

XSLT (embedded在下面的VBAstring)

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output version="1.0" encoding="UTF-8" indent="yes" /> <!-- Identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="@NULL"> </xsl:template> </xsl:stylesheet> 

VBA (作为子程序或函数合并到你的项目中,甚至通过Oracle XML文件path作为参数)

 Sub TransformXML() Dim xmlDoc As Object, xslDoc As Object, newDoc As Object Set xmlDoc = CreateObject("MSXML2.DOMDocument") Set xslDoc = CreateObject("MSXML2.DOMDocument") Set newDoc = CreateObject("MSXML2.DOMDocument") xmlDoc.Load "Original.xml" xmlDoc.async = False ' EMBEDDED XSLT ' 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:template match=" & Chr(34) & "@NULL" & Chr(34) & ">" _ & "</xsl:template>" _ & "</xsl:stylesheet>" xslDoc.async = False xmlDoc.transformNodeToObject xslDoc, newDoc newDoc.Save "OutputXML.xml" ' READY FOR FINAL IMPORT ' MsgBox "Successfully transformed XML!", vbInformation Set xmlDoc = Nothing Set xslDoc = Nothing Set newDoc = Nothing End Sub