gpt4 book ai didi

xml - 如何在 MSXML - VBA 中获取 XML 元素的数组索引?

转载 作者:行者123 更新时间:2023-12-04 20:35:31 24 4
gpt4 key购买 nike

我需要将 XML 文件转换为 Excel。所以我想检索 XML 作为名称值对并唯一地命名列。有什么方法可以获取节点的 XML 数组索引吗?下面是我想知道 productInfo 字段索引的示例 XML。

<productInfoRequest>
<CheckIn>false</CheckIn>
<timeStamp>2016-11-02T15:49:57.337-05:00</timeStamp>
<foodoInfo>
<Country>USA</Country>
<Currency>USD</Currency>
</foodoInfo>
<productInfo>
<itemNo>1</itemNo>
<itemName>Sample</itemName>
</productInfo>
<productInfo>
<itemNo>2</itemNo>
<itemName>Sample</itemName>
</productInfo>
<productInfo>
<itemNo>3</itemNo>
<itemName>Sample</itemName>
</productInfo>
<productInfo>
<itemNo>4</itemNo>
<itemName>Sample</itemName>
</productInfo>
</productInfoRequest>

Desired Output

请注意,这只是我给出的示例请求 xml。任何给定的 XML 都应转换为唯一的键值对键并加载到 excel 中

示例代码片段:

Sub GenKeyValues()

Dim xmlDoc As MSXML2.DOMDocument60
Dim xmlNodes As MSXML2.IXMLDOMNodeList
Dim xNode As MSXML2.IXMLDOMNode
Dim cNode As MSXML2.IXMLDOMNode
Dim ccNode As MSXML2.IXMLDOMNode
Dim KeyNo As Variant
Dim dic

Set dic = CreateObject("Scripting.Dictionary")

Dim CurrVal
Dim Cnt As Integer

CurrVal = <<<<<Im reading the XML from the file to a string from another method>>>>>
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
With xmlDoc
.async = False
.validateOnParse = True
.LoadXML CurrVal
End With

Set xmlNodes = xmlDoc.ChildNodes

cnt = 0

For Each xNode In xmlNodes

If xNode.HasChildNodes Then
For Each cNode In xNode.ChildNodes
If cNode.ChildNodes.Length > 1 Then
cnt = cnt + 1
For Each ccNode In cNode.ChildNodes
Key = ccNode.ParentNode.BaseName + CStr(cnt) + "_" + ccNode.BaseName
Val = ccNode.nodeTypedValue
dic.Add Key, Val
Next
Else
Key = cNode.BaseName
Val = cNode.nodeTypedValue
dic.Add Key, Val
End If
Next
End If
Next

For Each KeyNo In dic.Keys
MsgBox ("Key: " & KeyNo & " Value: " & dic(KeyNo))
Next

End Sub

我已检索以下 key :
foodoInfo0_Country
foodoInfo0_Currency
productInfo0_itemNo
productInfo0_itemName
productInfo1_itemNo
productInfo1_itemName
productInfo2_itemNo

productInfo2_itemName

最佳答案

考虑XSLT ,一种专用语言,旨在将 XML 文件转换为最终用途格式,包括其他 XML 文件、HTML 文件,甚至文本文件。在这里,XSLT 可以将您的结构转换为带有所需标题和数据行的 CSV 格式。 MSXML 可以运行 XSLT 1.0 脚本,避免嵌套 forif逻辑和数组或字典的使用。

XSLT (另存为 .xsl 文件以在 VBA 中读取;注意:XSL 脚本是 XML 文件)

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

<xsl:template match="/productInfoRequest">
<xsl:call-template name="rows">
<xsl:with-param name="data" select="foodoInfo|productInfo"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="rows">
<xsl:param name="data"/>

<!-- HEADERS -->
<xsl:for-each select="$data">
<xsl:value-of select="concat(name(), position(), '_', name(*[1]))"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="concat(name(), position(), '_', name(*[2]))"/>
<xsl:if test="position() != last()"><xsl:text>,</xsl:text></xsl:if>
</xsl:for-each>

<xsl:text>&#xa;</xsl:text>

<!-- DATA -->
<xsl:for-each select="$data">
<xsl:value-of select="concat(node()[1], ',', node()[2])"/>
<xsl:if test="position() != last()"><xsl:text>,</xsl:text></xsl:if>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

VBA

Public Sub RunXSLTtoCSV()
Dim xmlDoc As New MSXML2.DOMDocument60, xslDoc As New MSXML2.DOMDocument60
Dim txtOutput As String, csvfile As String

' LOAD XML AND XSL
xmlDoc.LoadXML CurrVal
xmlDoc.async = False
xslDoc.Load "C:\Path\To\XSLScript.xsl"
xslDoc.async = False

' TRANSFORM TO TEXT
txtOutput = xmlDoc.transformNode(xslDoc)

' SAVE TO CSV
csvfile = "C:\Path\To\CSV.csv"
Open csvfile For Output As #1
Print #1, txtOutput
Close #1

Set xslDoc = Nothing
Set xmlDoc = Nothing
End Sub

CSV 输出

当然这是一个 csv 文件,而不是 Excel 工作簿。因此,将内容保存或加载到工作簿中。

CSV Output Screenshot

关于xml - 如何在 MSXML - VBA 中获取 XML 元素的数组索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43192810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com