This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

A solution for combining/merging two TCX files (activies)

Former Member
Former Member
This weekend I needed to adjust my interval workout while it was in progress (yes, I needed a break!) This resulted in me having two different activities and two TCX files for each.

I searched and downloaded various software, but they didn't do exactly what I wanted. (Some didn't preserve the calories, and some turned the workout into a course, etc)

I then tried just copying all the laps from one TCX to the other using notepad, but that didn't work either. The distance was corrupt when I uploaded to Garmin Connect. I realized that the the individual laps in each activity have a cumulative distance tracker. So all I needed to do to make this work is offset the last distance tracked to all of the distances from the other activity.

I created a simple XSLT transform that can be applied to two TCX files and it will create a new merged activity.

Thought I'd share.

(Note, you'll need a XSLT processor like saxon/xalan or others)
  • Cheers

    Thanks yungoso...works like a charm
  • Former Member
    0 Former Member over 9 years ago
    Merging activity failure

    Hi there.

    I am very happy to have found this tool and wanted to thank you very much for putting it together and sharing it with us.
    However, I haven't been able to merge to files as each time I get an error (see the text I pasted below)

    So I decided to upload 2 files on my dropbox as a zip (https://dl.dropboxusercontent.com/u/...50/Archive.zip) and really I would be grateful if anyone could help with it and guide me to fix my mistake.
    I have a lot of activities that need to be merged as I didn't really know how to use my Garmin when I cycled from London to Breda ( Holland) and now i think it is a shame to have multiple short segments instead of the full length activity of each day.

    Thank you very much in advance.

    This is what I get when trying to merge:

    net.sf.saxon.trans.XPathException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:420)
    at net.sf.saxon.event.Sender.send(Sender.java:180)
    at net.sf.saxon.Controller.transform(Controller.java:1724)
    at CombineActivities.doConvert(CombineActivities.java:160)
    at CombineActivities.access$0(CombineActivities.java:148)
    at CombineActivities$3.actionPerformed(CombineActivities.java:125)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6525)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6290)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4881)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrap per.java:203)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerI mpl.java:999)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java: 117)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragm entScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:400)
    ... 41 more
    ---------
    org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrap per.java:203)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerI mpl.java:999)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java: 117)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragm entScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:400)
    at net.sf.saxon.event.Sender.send(Sender.java:180)
    at net.sf.saxon.Controller.transform(Controller.java:1724)
    at CombineActivities.doConvert(CombineActivities.java:160)
    at CombineActivities.access$0(CombineActivities.java:148)
    at CombineActivities$3.actionPerformed(CombineActivities.java:125)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6525)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6290)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4881)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
  • Former Member
    0 Former Member over 9 years ago
    Hello Azurely,

    I just got back from vacation and tried to get your files but the DropBox link does not work.

    If you still need help post a new link.
  • java combine tool works perfectly!

    i had three separate parts of a tour combined to one with this handy combine.jar tool.

    in Garmin activities open ride 1 and dowload as tcx
    same fore ride 2 and 3.

    Off course JAVA needs to installed on your pc. doubleclick the downloaded combine.jar file. Select ride 1 and 2 and combine. Copy A from screen and paste innew txt file. rename newfile.txt to combine.tcx.
    close jartool. doubleclick combine.jar again. select combine.tcx and ride3.tcx. do the combine trick again. copy paste into new text file. rename textfile again.
    in activiteis in garmin upload newest tcx file.
    DONE!
  • Former Member
    0 Former Member over 9 years ago
    Alternatively this Website might be useful to some of you

    https://www.fitfiletools.com/
  • Mac or no?

    I am pretty sure there is no reason this should not work on my Mac but I thought I would ask. I have followed the instructions and even updated the the very top of the file with the time, distance etc. totals as described early on. All (the two files) seems to compile properly (no errors) however Garmin connect fails after chewing on the file for a few minutes.

    I had a five minute warm up as the first segment (if that matters) and I thought maybe I had to delete the summary items for all other segments but I am just shooting in the dark.

    If you have any suggestions I would appreciate some pointers.... and BTW thank you for making this and even more for helping people over two years. When I looked at the first thread I never guessed that it would still be alive two years later. Impressive.

    Thanks
    Scott
  • Former Member
    0 Former Member over 9 years ago
    89720

    Great work! It worked like a charm.

    I'd be happy to work on making it prettier and adding multifile select + file saving let me know.
  • Hello, I tried several times to merge two activities, but without success :( I tried to put the first one is first, then the other, but the file upload in Garmin connect and only gives me that this is first uploaded. Can anyone help me where help is wrong?
  • Former Member
    0 Former Member over 9 years ago
    Hello Ts,

    It would help if you could attach your 2 files. They might be the problem.
  • Former Member
    0 Former Member over 9 years ago
    I just whipped up a quick and dirty Java program ... CombineActivities.jar


    Great tool; many thanks. Combined 2xTCX; result here: https://connect.garmin.com/modern/activity/1044641680 Time/distance looks correct, cf. other comment re 'missing half of the data'.