我试图使用Excel读取一些XML数据,因此我最终可以将其全部保存到单个Excel / CSV文件中供以后使用,但我遇到了一些问题。 XML文件的读取由Excel的解析器读取。以下是数据的示例:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<data>
<header>
<name>n</name>
<version>v</version>
<date>d</date>
</header>
<abcd>
<attr1>val1</attr1>
<attr2>val2</attr2>
<attr3>val3</attr3>
<efgh>
<attr4>val4</attr4>
<attr5>val5</attr5>
<attr6>val6</attr6>
<ijkl>
<attr7>val7</attr7>
<attr8>val8</attr8>
<attr9>val9</attr9>
</ijkl>
</efgh>
<attr10>val10</attr10>
<attr11>val11</attr11>
<attr12>val12</attr12>
</abcd>
在Data > From Other Sources > From XML Data Import
下的数据选项卡中找到的Excel XML解析器为我提供了输出:
name | version | date | attr1 | attr2 | attr3 | attr4 | attr5 | attr6
n v d
val1
val2
val3
val4 val5 val6
但我希望输出为:
name | version | date | attr1 | attr2 | attr3 | attr4 | attr5 | attr6
n v d val1 val2 val3 val4 val5 val6
或者,换句话说,我希望每个属性值都显示在同一行,直到<abcd>
标记再次出现。有没有办法强制Excel解析器执行此操作?或者,使用excel公式或VBA后,是否可以轻松地清理数据?
答案 0 :(得分:1)
XML是一种开放式树格式,它可以拥有与设计一样多的嵌套元素。但是,电子表格,数据集,数据库表格和其他平面结构是具有行和列的两个维度。因此,您需要将XML展平为每行一级的一个子/一个嵌套以进行正确的迁移:
<data>
<row>
<col>value</col>
<col>value</col>
<col>value</col>
</row>
<row>
<col>value</col>
<col>value</col>
<col>value</col>
</row>
</data>
使用VBA MSXML,您可以通过运行XSLT(旨在将XML文档转换为各种最终用途结构需求的专用语言)来展平。转换后,您可以使用Workbooks.OpenXML()将XML加载到Excel电子表格中。
XSLT 脚本(外部保存为.xsl以加载到VBA中)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="abcd"/>
</xsl:copy>
</xsl:template>
<xsl:template match="abcd">
<row>
<xsl:copy-of select="ancestor::data/header/*"/>
<xsl:copy-of select="attr1|attr2|att3"/>
<xsl:apply-templates select="efgh"/>
<xsl:copy-of select="attr10|attr11|attr12"/>
</row>
</xsl:template>
<xsl:template match="efgh">
<xsl:copy-of select="attr4|attr5|attr6"/>
<xsl:apply-templates select="ijkl"/>
</xsl:template>
<xsl:template match="ijkl">
<xsl:copy-of select="*"/>
</xsl:template>
</xsl:transform>
VBA 宏
Public Sub RunXSLT()
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")
' LOAD XML AND XSL DOCS '
xmlDoc.Load "C:\Path\To\Input.xml"
xmlDoc.async = False
xslDoc.Load "C:\Path\To\XSLTScript.xsl"
xslDoc.async = False
' TRANSFORM SOURCE TO OUTPUT '
xmlDoc.transformNodeToObject xslDoc, newDoc
newDoc.Save "C:\Path\To\Output.xml"
Set newDoc = Nothing
Set xslDoc = Nothing
Set xmlDoc = Nothing
' IMPORT OUTPUT INTO WORKBOOK '
Workbooks.OpenXML "C:\Path\To\Output.xml", , xlXmlLoadImportToList
End Sub
XML 输出
<?xml version="1.0" encoding="UTF-8"?>
<data>
<row>
<name>n</name>
<version>v</version>
<date>d</date>
<attr1>val1</attr1>
<attr2>val2</attr2>
<attr4>val4</attr4>
<attr5>val5</attr5>
<attr6>val6</attr6>
<attr7>val7</attr7>
<attr8>val8</attr8>
<attr9>val9</attr9>
<attr10>val10</attr10>
<attr11>val11</attr11>
<attr12>val12</attr12>
</row>
</data>
Excel 导入
name version date attr1 attr2 attr4 attr5 attr6 attr7 attr8 attr9 attr10 attr11 attr12
n v d val1 val2 val4 val5 val6 val7 val8 val9 val10 val11 val12