MS Access to XML 'Saved Export' produces different XML structure when re-exported

后端 未结 1 743
情话喂你
情话喂你 2021-01-21 16:00

I have a Microsoft Access database (via Office 2010) which is being used to manage course data, and I need to regularly export this data to a particular XML structure.

U

相关标签:
1条回答
  • 2021-01-21 16:30

    I can't quite re-create your issue in MS Access. I went through the manual XML Export wizard and Saved Export and both produce the same result, namely your last format where first two related tables (Courses and Occurrences) are nested with last table (OccurrenceUnits) stacked at the end. What I can say is your saved export is contingent on established relationships between tables and not simply an export of table or inner join SQL query of tables.

    However, consider a programming solution that specifically automates your exact structural needs. And what you need involves XSLT (the declarative programming language that re-styles, re-formats, re-structures XML documents). VBA can transform XML with XSLT scripts using the MSXML object. You can continue to run your saved export (using table relationships) and then load the external XML and XSLT files for the transformation.

    XSLT (save as external .xsl or .xslt to be used below)

    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                   xmlns:od="urn:schemas-microsoft-com:officedata"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"               
                   exclude-result-prefixes="od xsi">
    
    <xsl:output version="1.0" encoding="UTF-8" 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="Courses">
        <Courses>
            <xsl:copy-of select="CourseID"/>
            <xsl:copy-of select="CourseTitle"/>
            <xsl:for-each select="Occurences">
                <xsl:copy-of select="*"/>
                <xsl:variable name="occid" select="OccurenceID"/>
                <xsl:copy-of select="../../OccurrencesUnits[OccurenceID=$occid]"/>
            </xsl:for-each>        
        </Courses>
      </xsl:template>
    
      <xsl:template match="OccurrencesUnits"/>
    
    </xsl:transform>
    

    VBA subroutine (use behind command button or trigger event)

    Below are two options of XML export: 1) using your Saved Export object or 2) the automated Application.ExportXML where you add other related tables to Courses output:

    Private Sub XMLOutput_Click()
    
        Dim rawDoc As Object, xslDoc As Object, newDoc As Object
        Dim xmlstr As String, xslstr As String
        Dim otherTables As AdditionalData
    
        Set otherTables = Application.CreateAdditionalData
        otherTables.Add "Occurrences"
        otherTables.Add "OccurrencesUnits"        
        otherTables.Add "Units"        
    
        ' RUN SAVED XML EXPORT ' 
        'DoCmd.RunSavedImportExport "SavedXMLExportName"
    
        ' RUN AUTOMATED EXPORT XML WITH NESTED ADDITIONAL TABLES ' 
        Application.ExportXML acExportTable, "Courses", "C:\Path\To\Original\XMLfile.xml", _
                     , , , , , , AdditionalData:=otherTables
    
        ' LOAD XML AND XSL FILES '
        xmlstr = "C:\Path\To\Original\XMLfile.xml"
        xslstr = "C:\Path\To\XSLT\Script.xsl"
    
        Set rawDoc = CreateObject("MSXML2.DOMDocument")
        Set xslDoc = CreateObject("MSXML2.DOMDocument")
        Set newDoc = CreateObject("MSXML2.DOMDocument")
    
        rawDoc.async = False
        rawDoc.Load xmlstr
    
        xslDoc.async = False
        xslDoc.Load xslstr
    
        ' TRANSFORM TO NEW XML '
        rawDoc.transformNodeToObject xslDoc, newDoc
    
        ' SAVE NEW XML FILE '
        newDoc.Save "C:\Path\To\Output\XMLfile.xml"
    
        MsgBox "Successfully transformed xml!", vbInformation
    
    End Sub
    
    0 讨论(0)
提交回复
热议问题