在Excel中使用VBA进行选择性XML节点解析

时间:2018-07-19 08:35:33

标签: xml vba excel-vba

我是Mainframe资源,几乎不了解VBA。

我需要自动化该过程,以从XML文件中解析某些节点并将其显示在Excel中。 然后,我需要连接到DB2并从表中获取字段的值(与XML节点相同)并进行比较。

到目前为止,我已经能够解析XML,但是我的代码只是从每个节点打印文本。

它既不是有组织的也不是选择性的。

这是XML文件示例:

<?xml version="1.0" encoding="iso-8859-1"?>
<ServiceRequest
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.0">
    <RequestHeader>
        <ServiceName>ProcessAMLMessageService</ServiceName>
        <ApplicationVersion>1.0</ApplicationVersion>
    </RequestHeader>
    <RequestBody>
        <Arguments type="ContractApplicationAMLDetails">
            <ContractApplicationAMLDetails>
                <AMLDataLanguage>E</AMLDataLanguage>
                <AMLApplication>E-FORM</AMLApplication>
                <AMLApplicationVersionNumber>3.0.0</AMLApplicationVersionNumber>
                <LaunchingApplication>EApp</LaunchingApplication>
                <LaunchingApplicationVersionNumber>36.1</LaunchingApplicationVersionNumber>
                <AdvisorNumber>123456</AdvisorNumber>
                <Userid>U12345</Userid>
                <ContractDetails>
                    <ContractNumber>CONT1234</ContractNumber>
                    <SourceData>
                        <AMLAdvisorNumber>98765</AMLAdvisorNumber>
                        <IntendedUseOfAcctCode>IOAC</IntendedUseOfAcctCode>
                        <ThirdPartyInd>N</ThirdPartyInd>
                        <TrustInd/>
                        <EstateInd/>
                        <SourcesOfPayment>
                            <SourceOfPayment>
                                <SequenceNumber>1</SequenceNumber>
                                <PaymentSourceCode>IA</PaymentSourceCode>
                            </SourceOfPayment>
                            <SourceOfPayment>
                                <SequenceNumber>2</SequenceNumber>
                                <PaymentSourceCode>SP</PaymentSourceCode>
                            </SourceOfPayment>
                            <SourceOfPayment>
                                <SequenceNumber>3</SequenceNumber>
                                <PaymentSourceCode>IF</PaymentSourceCode>
                            </SourceOfPayment>
                        </SourcesOfPayment>
                    </SourceData>
                </ContractDetails>
                <Owners>
                    <Owner>
                        <PartyTypeCode>P</PartyTypeCode>
                        <Person>
                            <UniqueIdentifier>UNIQUE-IDENTIFIER-1</UniqueIdentifier>
                            <Surname>USER-NAME</Surname>
                            <FirstName>FIRST-NAME</FirstName>
                            <DateOfBirth>1967-03-01</DateOfBirth>
                            <OccupationOrPrincipalBusiness>Pilot</OccupationOrPrincipalBusiness>
                            <AMLPEPInd>Y</AMLPEPInd>
                            <SelfIdentifiedPEFPInd>N</SelfIdentifiedPEFPInd>
                            <SelfIdentifiedPEDPInd>Y</SelfIdentifiedPEDPInd>
                            <SelfIdentifiedHIOInd>Y</SelfIdentifiedHIOInd>
                            <ForeignTaxResidentInd>N</ForeignTaxResidentInd>
                            <CRSForeignTaxResidentInd>N</CRSForeignTaxResidentInd>
                            <PEDPDetails>
                                <PEDP>
                                    <UniqueIdentifier>UNIQUE-IDENTIFIER-2</UniqueIdentifier>
                                    <Surname>USER-2</Surname></Surname>
                                    <FirstName>FIRST-2</FirstName>
                                    <RelationshipCode>RC</RelationshipCode>
                                    <PositionCode>PC-1</PositionCode>
                                    <CountryText>COUNTRY-1</CountryText>
                                    <PEOrganizationText>COUNTRY-1 Council</PEOrganizationText>
                                </PEDP>
                            </PEDPDetails>
                            <HIODetails>
                                <HIO>
                                    <UniqueIdentifier>HIO UNIQUI ID-1</UniqueIdentifier>
                                    <Surname>ApplicantAHIOw</Surname>
                                    <FirstName>HIOFourE</FirstName>
                                    <RelationshipCode>SI</RelationshipCode>
                                    <PositionText>Political Party Leader</PositionText>
                                    <CountryText>The United Arab Emirates</CountryText>
                                    <PEOrganizationCode>H06</PEOrganizationCode>
                                </HIO>
                                <HIO>
                                    <UniqueIdentifier>HIO UNIQUI ID-2</UniqueIdentifier>
                                    <Surname>ApplicantAHIOx</Surname>
                                    <FirstName>HIOFourF</FirstName>
                                    <RelationshipCode>PA</RelationshipCode>
                                    <PositionText>Director</PositionText>
                                    <CountryText>France</CountryText>
                                    <PEOrganizationText>Chamber of Commerce</PEOrganizationText>
                                    <PEOrganizationCode>XX</PEOrganizationCode>
                                </HIO>
                            </HIODetails>
                            <FATCADetails/>
                        </Person>
                        <Address>
                            <AddressLine1>ADDRESS-1</AddressLine1>
                            <City>CITY-1</City>
                            <ProvinceCode>PC</ProvinceCode>
                            <PostalCode>N2N 2N2</PostalCode>
                            <CountryCode>CA</CountryCode>
                            <CountryText>Canada</CountryText>
                        </Address>
                    </Owner>
                </Owners>
            </ContractApplicationAMLDetails>
        </Arguments>
    </RequestBody>
</ServiceRequest>

这是我想出的代码:

Public Sub Convert_XML_To_Excel_Through_VBA()
    'Code from Officetricks.com
    'Add referece from Menu: "Tools -> References -> Microsoft XML Vn.0"
    Dim iRow As Integer, iCol As Integer
    Dim xmlDoc As MSXML2.DOMDocument, xmlRoot As MSXML2.IXMLDOMNode
    Dim xmlNodes As MSXML2.IXMLDOMNode, xmlData As MSXML2.IXMLDOMNode
    Set xmlDoc = New MSXML2.DOMDocument
    
    'Load & Wait till complete XML Data is loaded
    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load ("C:\Users\XML_FIle.xml")
    
    'XML Loaded. Now Read Elements One by One into XML DOM Objects
    Set xmlRoot = xmlDoc.DocumentElement
    Set xmlNodes = xmlRoot.FirstChild
    
    'Read XML Data and Load into Excel Sheet by each Node and Chile Node
    iRow = 0
    For Each xmlNodes In xmlRoot.ChildNodes
        iRow = iRow + 1
        iCol = 0
        
        For Each xmlData In xmlNodes.ChildNodes
            iCol = iCol + 1
            ThisWorkbook.Sheets(1).Cells(1, iCol) = xmlData.BaseName
            ThisWorkbook.Sheets(1).Cells(iRow, iCol) = xmlData.Text
        Next xmlData
    Next xmlNodes
End Sub

如果有人指出我正确的方向,那将是非常有义务的。 谢谢你。

1 个答案:

答案 0 :(得分:0)

您可以通过以下方式选择元素:

1)xpath(nodes2)例如

Set nodes2 = xmlDoc.SelectNodes("//Userid")

2)并在DOM结构(节点)中使用标签,例如

Set nodes = xmlDoc.getElementsByTagName("Person")

我很惊讶您的文档被解析,因为以下错误:

<Surname>USER-2</Surname></Surname>

应该是

<Surname>USER-2</Surname>

VBA:

Option Explicit
Public Sub Convert_XML_To_Excel_Through_VBA()
    Dim xmlDoc As MSXML2.DOMDocument60, xmlRoot As MSXML2.IXMLDOMNode
    Set xmlDoc = New MSXML2.DOMDocument60

    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load "C:\Users\XML_FIle.xml"
    Set xmlRoot = xmlDoc.DocumentElement

    Dim nodes As Object, nodes2, i  As Long
    Set nodes = xmlDoc.getElementsByTagName("Person"): Set nodes2 = xmlDoc.SelectNodes("//Userid")

    For i = 0 To nodes.Length - 1
        Debug.Print nodes(i).Text
        Debug.Print nodes2(i).Text
    Next i
End Sub

XML xpath查询:

xmlpath query


RE:您的更新

这里是一个选择并从中列出的示例

Option Explicit
Public Sub Convert_XML_To_Excel_Through_VBA()
    Dim xmlDoc As MSXML2.DOMDocument60, xmlRoot As MSXML2.IXMLDOMNode
    Set xmlDoc = New MSXML2.DOMDocument60

    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load "C:\Users\XML_FIle.xml"
    Set xmlRoot = xmlDoc.DocumentElement

    Dim userIds As Object, AMLAdvisorNumbers As Object, UniqueIdentifiers As Object, RelationshipCodes As Object, i As Long
    Set userIds = xmlDoc.SelectNodes("//Userid")
    Set AMLAdvisorNumbers = xmlDoc.SelectNodes("//AMLAdvisorNumber")
    Set UniqueIdentifiers = xmlDoc.SelectNodes("//AMLAdvisorNumber")
    Set RelationshipCodes = xmlDoc.SelectNodes("//RelationshipCode")

    For i = 0 To userIds.Length - 1
        Debug.Print userIds(i).Text
        Debug.Print AMLAdvisorNumbers(i).Text
        Debug.Print UniqueIdentifiers(i).Text
        Debug.Print RelationshipCodes(i).Text
    Next i
End Sub

它们的长度不一样,所以您不想使用上面显示的循环清空所有内容:

Debug.Print userIds.Length
Debug.Print AMLAdvisorNumbers.Length
Debug.Print UniqueIdentifiers.Length
Debug.Print RelationshipCodes.Length

以上显示,除最后一个长度为1外,其他所有长度为3。