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.
Unfortunately, I have found that the structure that is produced via the initial XML export is not then replicated when the 'saved export' is later re-run. I have conducted numerous tests and tried to research this online, but have not found a solution. Hoping somebody can please help!
The part of the database that is relevant looks like this: (this has been simplified from the original database, but the same problem still occurs).
Some contextual info: A 'Course' is the overarching training programme which may run on several occasions. An 'Occurrence' is a particular instance/running of a course that the student actually enrols onto. A 'Unit' is a particular taught section of that Occurrence (e.g. practicals, seminars). 'Units' can form part of multiple 'Occurrences', thus the requirement for the many-to-many bridge table 'OccurrencesUnits'. This structure has been carefully planned and we are not realistically able to change this (and hopefully shouldn't need to).
When I export to XML (External Data > XML File), I select to export data from all of these tables:
When the initial export is complete, the resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2015-11-25T16:09:31">
<Courses>
<CourseID>1</CourseID>
<CourseTitle>Meat Science</CourseTitle>
<Occurrences>
<OccurrenceID>1</OccurrenceID>
<OccurrenceTitle>Meat Science - 10 Credit Version</OccurrenceTitle>
<CourseID>1</CourseID>
<OccurrencesUnits>
<OccurrencesUnitsID>1</OccurrencesUnitsID>
<OccurrenceID>1</OccurrenceID>
<UnitID>1</UnitID>
</OccurrencesUnits>
</Occurrences>
<Occurrences>
<OccurrenceID>2</OccurrenceID>
<OccurrenceTitle>Meat Science - 20 Credit Version</OccurrenceTitle>
<CourseID>1</CourseID>
<OccurrencesUnits>
<OccurrencesUnitsID>2</OccurrencesUnitsID>
<OccurrenceID>2</OccurrenceID>
<UnitID>1</UnitID>
</OccurrencesUnits>
<OccurrencesUnits>
<OccurrencesUnitsID>3</OccurrencesUnitsID>
<OccurrenceID>2</OccurrenceID>
<UnitID>2</UnitID>
</OccurrencesUnits>
</Occurrences>
</Courses>
<Units>
<UnitID>1</UnitID>
<UnitTitle>Meat Safety</UnitTitle>
</Units>
<Units>
<UnitID>2</UnitID>
<UnitTitle>Meat Genetics</UnitTitle>
</Units>
</dataroot>
This is exactly the right data structure we want to have, whereby 'OccurrencesUnits' is nested within 'Occurrences'. I then save the export steps to use later within MS Access.
Unfortunately the problem occurs whenever I re-use this export step (via External Data > Saved Exports). This results in an XML file which is structured differently:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2015-11-25T16:10:34">
<Courses>
<CourseID>1</CourseID>
<CourseTitle>Meat Science</CourseTitle>
<Occurrences>
<OccurrenceID>1</OccurrenceID>
<OccurrenceTitle>Meat Science - 10 Credit Version</OccurrenceTitle>
<CourseID>1</CourseID>
</Occurrences>
<Occurrences>
<OccurrenceID>2</OccurrenceID>
<OccurrenceTitle>Meat Science - 20 Credit Version</OccurrenceTitle>
<CourseID>1</CourseID>
</Occurrences>
</Courses>
<OccurrencesUnits>
<OccurrencesUnitsID>1</OccurrencesUnitsID>
<OccurrenceID>1</OccurrenceID>
<UnitID>1</UnitID>
</OccurrencesUnits>
<OccurrencesUnits>
<OccurrencesUnitsID>2</OccurrencesUnitsID>
<OccurrenceID>2</OccurrenceID>
<UnitID>1</UnitID>
</OccurrencesUnits>
<OccurrencesUnits>
<OccurrencesUnitsID>3</OccurrencesUnitsID>
<OccurrenceID>2</OccurrenceID>
<UnitID>2</UnitID>
</OccurrencesUnits>
<Units>
<UnitID>1</UnitID>
<UnitTitle>Meat Safety</UnitTitle>
</Units>
<Units>
<UnitID>2</UnitID>
<UnitTitle>Meat Genetics</UnitTitle>
</Units>
</dataroot>
In this version, you can see that 'OccurrencesUnits' no longer resides within 'Occurrences', and now sits complete outside of the 'Occurrences' and 'Courses' tag. This is causing us a lot of difficulty as we need to have it in the original structure.
I don't understand why a 'Saved Export' does not actually replicate the original export from which it was saved. Could this be a bug in MS Access, or am I doing something wrong? I have tried re-creating the database several times, and have also tried exporting with/without an XML Schema, but cannot find a solution.
Hoping somebody can please help - It would be very much appreciated! Many thanks.
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
来源:https://stackoverflow.com/questions/33921974/ms-access-to-xml-saved-export-produces-different-xml-structure-when-re-exporte

