如何使用其 baseName 而不是 Item(#) 来选择 XML 子节点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14666678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:52:09  来源:igfitidea点击:

How to select XML child node using its baseName instead of Item(#)?

xmlvbaexcel-vbaxml-parsingexcel

提问by Peter L.

I'm a little bit stuck with the following: I try to get currency rates from the local bank website to Excel using VBA - mostly for XML parsing practice, I'd say this is my first serious attempt.

我有点坚持以下几点:我尝试使用 VBA 将货币汇率从当地银行网站获取到 Excel - 主要用于 XML 解析实践,我想说这是我第一次认真的尝试。

After several hours of googling and reading related SO questions I got the more or less working solution, but I'd like to optimize it for better XML understating. So far so good, the question is:

经过几个小时的谷歌搜索和阅读相关的 SO 问题,我得到了或多或少的工作解决方案,但我想对其进行优化以更好地理解 XML。到目前为止一切顺利,问题是:

<LIST_RATE>
    <RATE ISO="EUR" Code="978">
        <TITLE>Евро</TITLE>
        <CODE>978</CODE>
        <ISO>EUR</ISO>
        <DATE>Thu, 31 Jan 2013 09:00:00 GMT</DATE>
        <BUY>11550.0000</BUY>
        <SELL>11820.0000</SELL>
        <QUANTITY>1</QUANTITY>
    </RATE>
    <RATE ISO="RUB" Code="643">
        <TITLE>Российский рубль</TITLE>
        <CODE>643</CODE>
        <ISO>RUB</ISO>
        <DATE>Thu, 31 Jan 2013 09:00:00 GMT</DATE>
        <BUY>279.0000</BUY>
        <SELL>292.0000</SELL>
        <QUANTITY>1</QUANTITY>
    </RATE>
    <RATE ISO="USD" Code="840">
        <TITLE>Доллар США</TITLE>
        <CODE>840</CODE>
        <ISO>USD</ISO>
        <DATE>Thu, 31 Jan 2013 09:00:00 GMT</DATE>
        <BUY>8570.0000</BUY>
        <SELL>8710.0000</SELL>
        <QUANTITY>1</QUANTITY>
    </RATE>
</LIST_RATE>

For the above XML part (just in case - this is the link to full XML: http://www.priorbank.by/CurratesExportXml.axd?channel=9) I'm looping through RATEchild nodes of LIST_RATEnode using the following code:

对于上述 XML 部分(以防万一 - 这是完整 XML 的链接:http: //www.priorbank.by/CurratesExportXml.axd?channel =9)我正在使用以下代码循环RATE节点的子节点LIST_RATE

For Each RATE_Node In LIST_RATE_Node.ChildNodes
    CurrencyCode = RATE_Node.ChildNodes.Item(2).Text 'ISO node
    RateValue = CSng(Replace(RATE_Node.ChildNodes.Item(4).Text, ".", ",")) 'BUY node
    [rest of code]
Next

The code is working fine, but I'd like to select RATEnode child nodes somehow using their namesinstead of Item(#). I tried selectSingleNode, but I'm not at all familiar with XPath, and the notation that I used always returned the very first <RATE ISO="EUR" Code="978">values. getElementsByTagNamereturns the whole bunch of nodes, and so on.

该代码工作正常,但我想选择RATE节点的子节点以某种方式使用他们的名字来代替Item(#)。我试过了selectSingleNode,但我对 XPath 一点也不熟悉,而且我使用的符号总是返回第一个<RATE ISO="EUR" Code="978">值。getElementsByTagName返回整个节点,依此类推。

I read a lot of related SO questions, but still stuck. I'm pretty sure the solution is simple - I just need to make all the ends meet. Any advice or guidance to the right direction will be highly appreciated. Thanks in advance!

我阅读了很多相关的 SO 问题,但仍然卡住了。我很确定解决方案很简单 - 我只需要让所有的结果都满足。任何对正确方向的建议或指导将不胜感激。提前致谢!

回答by dee

    Option Explicit

    Private Const xml As String = "<LIST_RATE>" & _
        "<RATE ISO='EUR' Code='978'>" & _
            "<TITLE>????</TITLE>" & _
            "<CODE>978</CODE>" & _
            "<ISO>EUR</ISO>" & _
            "<DATE>Thu, 31 Jan 2013 09:00:00 GMT</DATE>" & _
            "<BUY>11550.0000</BUY>" & _
            "<SELL>11820.0000</SELL>" & _
            "<QUANTITY>1</QUANTITY>" & _
        "</RATE>" & _
    "</LIST_RATE>"

    Sub test()
        Dim xmlDocument As MSXML2.DOMDocument60
        Set xmlDocument = New DOMDocument60

        If Not xmlDocument.LoadXML(xml) Then
            Err.Raise xmlDocument.parseError.ErrorCode, , xmlDocument.parseError.reason
        End If

        Dim listRateNode As IXMLDOMNode
        Dim rateNode As IXMLDOMNode
        Dim isoNode As IXMLDOMNode
        For Each listRateNode In xmlDocument.ChildNodes
            For Each rateNode In listRateNode.ChildNodes
                Set isoNode = rateNode.SelectSingleNode("ISO")
            Next
        Next

        Set isoNode = Nothing
        Set isoNode = xmlDocument.SelectSingleNode("/LIST_RATE/RATE[ISO='EUR']/ISO")
    End Sub

SelectSingleNode should work. If SelectSingleNode is used on RATE_NODE then use just rateNode.SelectSingleNode("ISO"). On the xml-document u can use xmlDocument.SelectSingleNode("/LIST_RATE/RATE[ISO='EUR']/ISO")to find iso node with value EUR. Is this helpfull for u?

SelectSingleNode 应该可以工作。如果在 RATE_NODE 上使用 SelectSingleNode,则只使用rateNode.SelectSingleNode("ISO"). 在 xml 文档中,您可以使用它xmlDocument.SelectSingleNode("/LIST_RATE/RATE[ISO='EUR']/ISO")来查找值为 EUR 的 iso 节点。这对你有帮助吗?