我想将包含运动数据的TCX文件反序列化为一些我的本地/临时对象。我使用了XSD schema describing这样的格式,并使用xsd2code创建了类。
之后我能够将XML反序列化为适当的对象,并且deserialzator没有抛出任何异常。但是当我开始扩展组件的行为时,我注意到某些字段不是正确的全域。
问题在于阅读标签Track。子结构中的反序列化Lap显示所有数据,但轨道号显示为0。
有没有办法触发反序列化器正确解释它?我错过了一些属性吗?即使没有例外,为什么它没有正确阅读。
我知道,很难解释并将所有需要的类放入评论中 - 所以我分享了我的current status here并写下:GetUnifiedData_WhenTrackPointsAreGivenInTcx_UnifiedTrackPointShouldRetreiveIt()没有通过并显示我的问题。
<Activities>
<Activity Sport="Running">
<Id>2015-01-25T12:14:34Z</Id>
<Lap StartTime="2015-01-25T12:14:34Z">
<TotalTimeSeconds>507.0989990</TotalTimeSeconds>
<DistanceMeters>1000.0000000</DistanceMeters>
<MaximumSpeed>2.5790000</MaximumSpeed>
<Calories>95</Calories>
<AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
<Value>155</Value>
</AverageHeartRateBpm>
<MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
<Value>173</Value>
</MaximumHeartRateBpm>
<Intensity>Resting</Intensity>
<TriggerMethod>Distance</TriggerMethod>
<Track>
<Trackpoint>
<Time>2015-01-25T12:14:34Z</Time>
<Position>
<LatitudeDegrees>50.8918607</LatitudeDegrees>
<LongitudeDegrees>16.7403161</LongitudeDegrees>
</Position>
<AltitudeMeters>233.1999969</AltitudeMeters>
<DistanceMeters>0.0000000</DistanceMeters>
<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
<Value>88</Value>
</HeartRateBpm>
<Extensions>
<TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2" CadenceSensor="Footpod">
<Speed>0.0000000</Speed>
</TPX>
</Extensions>
</Trackpoint>
</Track>
<Track>
</Track>
<Extensions>
<FatCalories xmlns="http://www.garmin.com/xmlschemas/FatCalories/v1">
<Value>0</Value>
</FatCalories>
<LX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
<AvgSpeed>1.9720000</AvgSpeed>
</LX>
</Extensions>
</Lap>
</Activity>
</Activities>
答案 0 :(得分:1)
问题是你的数据模型是错误的。在下面的摘录中,您会在Track
元素下方看到两个Lap
元素:
<?xml version="1.0" encoding="utf-16" standalone="no"?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/ActivityExtension/v2 http://www.garmin.com/xmlschemas/ActivityExtensionv2.xsd http://www.garmin.com/xmlschemas/FatCalories/v1 http://www.garmin.com/xmlschemas/fatcalorieextensionv1.xsd http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">
<Activities>
<Activity Sport="Running">
<Id>2015-01-25T12:14:34Z</Id>
<Lap StartTime="2015-01-25T12:14:34Z">
<Track>
<Trackpoint>
<Time>2015-01-25T12:14:34Z</Time>
... etc etc
</Trackpoint>
<Trackpoint>
... etc etc
</Trackpoint>
</Track>
<Track>
<Trackpoint>
... etc etc
<Trackpoint>
</Track>
但是,在您的数据模型中,Track
是Lap
的单例属性,包含TrackPoint_t
条目数组。当XmlSerializer
遇到多个Track
元素时,它无法反序列化它们。
因此,您的数据模型需要如下所示。引入中间类Track_t
:
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2")]
public class Track_t
{
public Track_t()
{
this.Track = new List<Trackpoint_t>();
}
[System.Xml.Serialization.XmlElement("TrackPoint", typeof(Trackpoint_t), IsNullable = false)]
public List<Trackpoint_t> Track { get; set; }
}
按如下方式修改ActivityLap_t
:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.34234")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2")
]
public partial class ActivityLap_t
{
private List<Track_t> _track; // Change type to `Track_t`
public ActivityLap_t()
{
this._extensions = new Extensions_t();
this._track = new List<Track_t>(); // Change type to `Track_t`
this._maximumHeartRateBpm = new HeartRateInBeatsPerMinute_t();
this._averageHeartRateBpm = new HeartRateInBeatsPerMinute_t();
}
// Change type to `Track_t` and change attribute to `XmlElement`
[System.Xml.Serialization.XmlElement("Track", typeof(Track_t), IsNullable = false)]
public List<Track_t> Track
{
get { return this._track; }
set { this._track = value; }
}
// Remainder unchanged.
}
您还需要以同样的方式修改Course_t
。
xsd
确实指定了Track_t
类型的存在,并且ActivityLap_t
可以包含此类型的无限数量的Track
元素,因此不知何故XSD已被转换分类错误:
<xsd:complexType name="ActivityLap_t">
<xsd:sequence>
<xsd:element name="TotalTimeSeconds" type="xsd:double" />
<xsd:element name="DistanceMeters" type="xsd:double" />
<xsd:element name="MaximumSpeed" type="xsd:double" minOccurs="0" />
<xsd:element name="Calories" type="xsd:unsignedShort" />
<xsd:element name="AverageHeartRateBpm" type="HeartRateInBeatsPerMinute_t" minOccurs="0" />
<xsd:element name="MaximumHeartRateBpm" type="HeartRateInBeatsPerMinute_t" minOccurs="0" />
<xsd:element name="Intensity" type="Intensity_t" />
<xsd:element name="Cadence" type="CadenceValue_t" minOccurs="0" />
<xsd:element name="TriggerMethod" type="TriggerMethod_t" />
<xsd:element name="Track" type="Track_t" minOccurs="0" maxOccurs="unbounded" /> <!-- Notice that maxOccurs is unbounded so "Track" needs to be a list -->
<xsd:element name="Notes" type="xsd:string" minOccurs="0" />
<xsd:element name="Extensions" type="Extensions_t" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
You can extend Training Center by adding your own elements from another schema here.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="StartTime" type="xsd:dateTime" use="required" />
</xsd:complexType>
和
<xsd:complexType name="Track_t">
<xsd:sequence>
<xsd:element name="TrackPoint" type="TrackPoint_t" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>