Closed mjunkmyjunk closed 3 years ago
I have a somewhat silly suggestion, but I hope it's somewhat reasonable from a certain perspective. Do you actually have to ready any data from these attributes? If not, the simplest approach would be to remove them from your coding keys and the list of properties on the type you're decoding into.
If you do need values of these attributes, would you mind explaining how you intend to use them?
Its not actually a silly idea. Its just that I'm at the point where it's a "I don't know".
As Far as I can tell, there is no actual usage of these data/tags at all. At least for my app's usage, I do not care about them at all, but the upstream Pod (TcxDataProtocol) is/has them as part of their package (which I'm using) and will exit w/ error.
There's also other instances within the XML file which I do use. (I'm pulling the Watts) which is part of the Extensions tag.
eg: variation No.1
<Extensions>
<ns3:TPX>
<ns3:Speed>0.0</ns3:Speed>
<ns3:Watts>84</ns3:Watts>
</ns3:TPX>
</Extensions>
eg: variation No.2
<Extensions>
<TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
<Speed>0.0</Speed>
<Watts>84</Watts>
</TPX>
</Extensions>
But I noticed that these do not fail. As these are handled this way (which generally just ignores the <TPX xmlns>
or <ns3:TPX>
tag
https://github.com/FitnessKit/TcxDataProtocol/blob/dd1234588067923bcf38e0eb39b74aee4c5c2c14/Sources/TcxDataProtocol/TcxExtensions/ActivityExtension.swift#L117
/// Coding Keys
public enum CodingKeys: String, CodingKey {
case speed = "ns3:Speed"
case runCadence = "ns3:RunCadence"
case watts = "ns3:Watts"
//attribute
case cadenceSensor = "ns3:CadenceSensorType"
}
/// Alternate Coding Keys
public enum AlternateCodingKeys: String, CodingKey {
case speed = "Speed"
case runCadence = "RunCadence"
case watts = "Watts"
//attribute
case cadenceSensor = "CadenceSensorType"
}
Yes, namespace prefix is stripped by default, you'll have to set shouldProcessNamespaces
to true
if you'd like the parser to be namespace-sensitive
Thanks for the link.
Is there any capability to address the instances of ignoring / skipping these tags? Like a "ignoreIfNotPresent"?
Did you try making their corresponding properties optional?
Ignoring and skipping attributes is only possible if you make properties that match them optional or remove them completely. Otherwise it's unclear what the value of that property should be if an attribute is not present.
Could you provide guidance on how to make them "optional" The possible issue that I foresee if that these conditions can also influence the generation (encoding) of the data into a TCX file. (Its entirely possible that a malformed Header XMLxx tags would render these TCXs not valid and can't be accepted into these Garmin / Strava and others sites.
I will need to see how exactly your types and properties into which you decode these attributes look like to provide such guidance. Would you be able to share a more complete example of Swift types that you use for decoding? Snippets with only coding keys aren't enough.
Thanks! The Upstream pod which I'm using is this -> https://github.com/FitnessKit/TcxDataProtocol The example TCX file I have shared in a zip file -> https://github.com/MaxDesiatov/XMLCoder/files/7104615/zzz_Demo.STRAVA.-copy.tcx.zip
For decoding, I'm essentially using these lines (from the TcxDataProtocol website)
let tcxUrl = URL(fileURLWithPath: "TestFile" + ".tcx")
let tcxData = try? Data(contentsOf: tcxUrl)
if let tcxData = tcxData {
let tcxFile = try? TcxFile.decode(from: tcxData)
}
I'm not exactly sure what you mean by "share a more complete example of Swift types that you use for decoding" aa I'm basically just using the pod and doing the decoding per the readme.
Note: I do realise that this is basically not an issue w/ XMLCoder
, but quite possibly how the upstream pod is handling the TCX/XML, but I would like to learn and get this settled. 🙏
Right, I didn't realize that library was involved. I think they should update their code here https://github.com/FitnessKit/TcxDataProtocol/blob/master/Sources/TcxDataProtocol/Elements/TrainingCenterDatabase.swift#L34-L53
to something like
/// XSI Schema Location
var schemaLocation: String? = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"
/// UserProfile Schema
var xmlnsNs2: String? = "http://www.garmin.com/xmlschemas/UserProfile/v2"
/// ActivityExtension Schema
var xmlnsNs3: String = "http://www.garmin.com/xmlschemas/ActivityExtension/v2"
/// ProfileExtension Schema
var xmlnsNs4: String? = "http://www.garmin.com/xmlschemas/ProfileExtension/v1"
/// ActivityGoals Schema
var xmlnsNs5: String? = "http://www.garmin.com/xmlschemas/ActivityGoals/v1"
/// TrainingCenterDatabase Schema
var xmlns: String? = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"
/// Schema
var xmlnsXsi: String? = "http://www.w3.org/2001/XMLSchema-instance"
That would make it use optional String?
instead of String
and hopefully will make it work with your variety of files.
this is a "duh" moment for me. When you mean optional`` I didn't even realise it was going to be as simple as putting the
?into the
String?```
I just tried this and it worked for a variety of files that I threw at the decoder. Strava and Tapiriik.Sync works. (Ride with GPS has weird structure and doesn't have element tags at all. Since I'm not entirely sure what would happen if I made ALL the tags optional)
I also tested TCX generation w/ these changes and it works! Thanks!!
Happy to help 🙂 Do you think there may be any more issues with this approach? Can the issue be closed otherwise?
Oh Yes.. yes.. I forgot to close it..
Thanks again!!
I'm working on a fitness app that uses the pod from TcxDataProtocol ( https://github.com/FitnessKit/TcxDataProtocol/issues/10#issue-987377764 ) and having some issues in decoding some TCX files due to the way how TCXs are formatted across different sites.
eg: (From Strava)
From Garmin
From: RideWithGPS
As you can see, the headers are all slightly different.
This is what the current
CodingKeys
look like and if I were to manually comment out the missing cases, then the decoding process will go thru. I'm hoping to get some pointers as to how to make this decoding process a little bit more flexible.https://github.com/FitnessKit/TcxDataProtocol/blob/master/Sources/TcxDataProtocol/Elements/TrainingCenterDatabase.swift
Thanks.
Attached is an example file. zzz_Demo(STRAVA)-copy.tcx.zip
This is the error