从WS导入XML并在VBA中的访问表中进行解析

时间:2018-10-30 19:34:33

标签: xml vba xml-parsing access-vba

我正在从Web服务导入数据。我很成功,但是数据导入了3个表。我发现了我认为可以使用的各种选项,但对于哪种选择最好,最有意义却感到困惑。

我找到的选项是

使用XSLT转换XML 包括XPATH在内的多种解析方式

真的,我已经读了太多即时消息,使我对应该做的事情感到困惑。

这是XML

<ArrayOfVehicle xmlns="http://schemas.datacontract.org/2004/07/Xata.Ignition.WebServiceAPI.Contracts.DataContract.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Vehicle>
        <AllowTrailerInspection>true</AllowTrailerInspection>
        <Auxiliary>None</Auxiliary>
        <CompanyName>Company</CompanyName>
        <CompanySID>1234</CompanySID>
        <Country>USA</Country>
        <EldVehicle>true</EldVehicle>
        <FuelDrawCapacity>0</FuelDrawCapacity>
        <GrossVehicleWeight>0</GrossVehicleWeight>
        <HP>0</HP>
        <HUT>false</HUT>
        <HasBerth>false</HasBerth>
        <HasElectronicEngine>true</HasElectronicEngine>
        <HosExempt>false</HosExempt>
        <IFTA>true</IFTA>
        <InstallDate>2018-10-01T13:01:00</InstallDate>
        <LicensePlate></LicensePlate>
        <ManualVIN>false</ManualVIN>
        <Manufacture></Manufacture>
        <ManufactureDate>1900-01-01T00:00:00</ManufactureDate>
        <Model></Model>
        <ModifiedBy>331</ModifiedBy>
        <ModifiedDate>2018-10-19T20:26:03.648543</ModifiedDate>
        <OBCType>ABCRelay</OBCType>
        <Odometer>0</Odometer>
        <OdometerDate>2018-10-01T04:00:00</OdometerDate>
        <OrganizationID>ABCLTL</OrganizationID>
        <OrganizationName>ABCLTL</OrganizationName>
        <OrganizationSID>32</OrganizationSID>
        <OwnerOperator>false</OwnerOperator>
        <PowerAxles>1</PowerAxles>
        <ResourceGroupIdList xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:string>NOR DISPATCH</a:string>
        </ResourceGroupIdList>
        <SID>34163</SID>
        <StateProvince>Texas</StateProvince>
        <Status>Active</Status>
        <StraightTruck>false</StraightTruck>
        <TGTNumber>123456</TGTNumber>
        <TransmissionMfg></TransmissionMfg>
        <TransmissionType></TransmissionType>
        <Type>Tractor</Type>
        <UserDefinedField1></UserDefinedField1>
        <UserDefinedField2></UserDefinedField2>
        <UserDefinedField3></UserDefinedField3>
        <UserDefinedField4></UserDefinedField4>
        <UserDefinedField5></UserDefinedField5>
        <VIN>1FVAHGFCXAJJR8537</VIN>
        <VehicleName>001234SCAC</VehicleName>
        <Year></Year>
    </Vehicle>
    <Vehicle>

我只想导入

<VehicleName>
<TGTNumber> and
<a:string> inside of <ResourceGroupIDList....

这是我到目前为止在VBA中拥有的

Public Sub UpdateTrucks(strUID As String, strPassword As String)
    'Debug.Print strDate
    Dim reader As New XMLHTTP60
    Dim strUserID As String
    Dim strRequest As String
    Dim strSQL As String
    Dim rs As DAO.Recordset



    strSQL = "tblResourceGroups1"   'defines the Table result that you want to loop
    Set rs = CurrentDb.OpenRecordset(strSQL)
    strUserID = "1234567|" & strUID
    strPassword = strPassword

    If Not rs.BOF And Not rs.EOF Then
    rs.MoveFirst
    While (Not rs.EOF)

            strRequest = "http://ws.Website.com/VehicleWebService.svc/vehicles/?ResourceGroupID=" & rs.Fields("ResourceGroupName")
            'Debug.Print strRequest
            reader.Open "GET", strRequest, rs.Fields("ResourceGroupName"), strUserID, strPassword
            reader.send

                Do Until reader.ReadyState = 4
                    DoEvents
            Loop

            If reader.status = 200 Then
            'importXML

            'current
            Set doc = reader.responseXML
            doc.Save "C:\Data\Table.xml"
            Application.ImportXML "C:\Data\Table.xml", acStructureAndData

                ElseIf reader.status = 401 Then
                   MsgBox "Unable to authenticate. The username and password do not match with the system."
                ElseIf reader.status = 500 Then
                   MsgBox "Due to an internal issue the system is unable to take the desired request. Please try again later."
            End If

        rs.MoveNext
      Wend
    Else
        MsgBox "Unable to import data."

    End If

    rs.Close
    Set rs = Nothing


End Sub

任何对我应该走的方向的帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

考虑运行XSLT,这是一种专用语言,旨在转换XML文件(例如提取需求)。在检索Web XML对象之后并在调用ImportXML之前运行XSLT脚本。

具体地说,下面的XSLT运行Identity Transform(按原样复制文档),然后从所有 Vehicle 节点中提取三个所需的子元素。在这里,XSLT将默认名称空间映射到 doc 前缀。

XSLT (另存为.xsl文件,特殊的.xml文件)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:doc="http://schemas.datacontract.org/2004/07/Xata.Ignition.WebServiceAPI.Contracts.DataContract.Entities"
                              xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">                            
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- IDENTITY TRANSFORM -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="doc:Vehicle">
    <xsl:copy>
      <xsl:copy-of select="doc:VehicleName|doc:TGTNumber|doc:ResourceGroupIdList/a:string"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

VBA

' ADD MSXML, v6.0 REFERENCE UNDER TOOLS
Dim xmlDoc As New MSXML2.DOMDocument60, xslDoc As New MSXML2.DOMDocument60, newDoc As New MSXML2.DOMDocument60

... same code ...

' WEB XML DOC
Set doc = reader.responseXML

' LOAD XML AND XSL FILES
xmlDoc.async = False
xmlDoc.LoadXML doc.XML

xslDoc.async = False
xslDoc.Load "C:\Data\XSLT_Script.xsl"

' TRANSFORM XML
xmlDoc.transformNodeToObject xslDoc, newDoc

' OUTPUT TRANSFORMED XML
newDoc.Save "C:\Data\Table.xml"

' IMPORT TRNASFORMED XML
Application.ImportXML "C:\Data\Table.xml", acStructureAndData

... same code ...

XML (已转换)

<?xml version="1.0" encoding="UTF-16"?>
<ArrayOfVehicle xmlns="http://schemas.datacontract.org/2004/07/Xata.Ignition.WebServiceAPI.Contracts.DataContract.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Vehicle>
        <a:string xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">NOR DISPATCH</a:string>
        <TGTNumber>123456</TGTNumber>
        <VehicleName>001234SCAC</VehicleName>
    </Vehicle>
</ArrayOfVehicle>

MS访问表

string       TGTNumber  VehicleName
NOR DISPATCH    123456   001234SCAC