我正在构建一个从API下载的Excel文件 .
它可以从URL模式元数据中自动生成XmlMap . 但是,我需要将XmlMap元素映射到ListObjects,以便提取数据并放入工作表 .
执行此操作的代码是每个项目的 range.Xpath.SetValue map xPath
(来自MSDN):
Sub CreateXMLList()
Dim mapContact As XmlMap
Dim strXPath As String
Dim lstContacts As ListObject
Dim objNewCol As ListColumn
' Specify the schema map to use.
Set mapContact = ActiveWorkbook.XmlMaps("Contacts")
' Create a new list.
Set lstContacts = ActiveSheet.ListObjects.Add
' Specify the first element to map.
strXPath = "/Root/Person/FirstName"
' Map the element.
lstContacts.ListColumns(1).XPath.SetValue mapContact, strXPath
' Specify the second element to map.
strXPath = "/Root/Person/LastName"
' Add a column to the list.
Set objNewCol = lstContacts.ListColumns.Add
' Map the element.
objNewCol.XPath.SetValue mapContact, strXPath
strXPath = "/Root/Person/Address/Zip"
Set objNewCol = lstContacts.ListColumns.Add
objNewCol.XPath.SetValue mapContact, strXPath
End Sub
这是架构输出:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<xsd:element name="root" nillable="true" >
<xsd:complexType>
<xsd:sequence minOccurs="0">
<xsd:element minOccurs="0" maxOccurs="unbounded" nillable="true" name="list-item" form="unqualified">
<xsd:complexType>
<xsd:sequence minOccurs="0">
<xsd:element name="data_source_organization"
minOccurs="0"
nillable="true"
type="xsd:string"
form="unqualified"
/>
<xsd:element name="survey_name"
minOccurs="0"
nillable="true"
type="xsd:string"
form="unqualified"
/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
这是数据(如果使用GUI,Excel将自动从中获取模式并创建XmlMap):
<root xsi:noNamespaceSchemaLocation="/api/domain/schema/?format=xml">
<list-item>
<data_source_organization>An org</data_source_organization>
<survey_name>A Survey</survey_name>
</list-item>
<list-item>
<data_source_organization>An org</data_source_organization>
<survey_name>Another Survey</survey_name>
</list-item>
</root>
但是我不想指定XPath字符串 - 我希望Excel从模式元数据中获取所有内容,就像使用GUI功能一样(数据,获取外部数据,从其他来源,XML,粘贴URL) - 这会自动创建XML映射,在工作表上创建ListObject,映射源数据中的每一列,以及抓取和显示数据 . (如果您录制宏执行此操作,则会跳过映射步骤 . )
-
我可以将XmlMap指向单元格,范围或ListObject吗?
-
我可以迭代XmlMap并检索每个列表项XPath吗?
-
其他一些方式?
要试验/重现,将上述XML保存为文件,然后按如下方式创建子:
Set currentMap = ActiveWorkbook.XmlMaps.Add("C:\path\to\schema.xml", "root")
currentMap.DataBinding.LoadSettings "path\to\data.xml"
' Do something to map the XmlMap elements to cells in the spreadsheet
' eg, objNewCol.XPath.SetValue currentMap, "root/data_source_organization"
' But some method that does not involve naming the Xml paths but iterates the schema
currentMap.DataBinding.Refresh
如果XmlMap映射到单元格,那么这些单元格将填充数据 .
3 回答
考虑使用Workbooks.OpenXML方法,因为您的XML文件是扁平且简单的,具有单子级别,以便于表格导入:
现在,如果您的XML与嵌套子元素很复杂,请考虑构建并运行XSLT,这是专门用于转换XML文件的专用语言 . 可以使用MSXML库自动进行此类转换,该库可用作VBA引用 . 注意:XSLT不是XSD架构文件,而是包含XPath的可扩展样式表系列的一部分 .
XSLT下面从原始XML中删除命名空间 . 但是脚本可以用于将嵌套的复杂结构展平为扁平的,简单的结构,例如您发布的示例 .
XSLT (另存为.xsl文件;从文档中删除任何命名空间和属性)
VBA
这是动态确定列名的起点 . 它会在即时窗口中打印有关每个节点的一些信息 . 需要进一步的工作来以有意义的方式提取列的名称:
此代码映射到表,但它不会自动执行 . 它确实显示了正确的列 Headers :
Expenses.xml
Expenses.xsd
参考