从XSD创建的类的反序列化并不包含所有数据 [英] Deserialization to classes created from XSD does not contain all data
问题描述
我想将包含运动数据的TCX文件反序列化为某些本地/临时对象。我使用了 XSD模式描述这样的格式,并使用xsd2code创建了类。
I wanted to deserialize TCX files containing sport data into some my local/temporary object. I used XSD schema describing such format and created classes using xsd2code.
之后,我能够将XML反序列化为适当的对象,并且deserialzator不会引发任何异常。但是,当我开始扩展组件的行为时,我注意到某些字段不是正确的全字段。
After that I was able to deserialize XML into proper object and the deserialzator didn't throw any exception. But when I started to expand behaviour of component I noticed that some fields are not properly fullfield.
问题在于读取跟踪标签。子结构中的反序列化Lap可以正确显示所有数据,但轨道数字显示为0。
The problem is about reading the tags Track. Deserialized Lap in substructure shows all data properly, but the Tracks number is displayed as 0.
有什么方法可以触发反序列化器正确解释它吗?我错过了一些属性吗?为什么即使没有例外也无法正确阅读它。
Is there any way to trigger deserializer to interpret it properly? Did I miss some attribute? Why it is not reading it properly even if there was no exception.
我知道,很难解释所有需要的类并将其置于注释中,所以我分享我的<一个href = https://dl.dropboxusercontent.com/u/113376/Sport%20Analyzer%20Solution.zip rel = nofollow>此处的当前状态,并只写:GetUnifiedData_WhenTrackPointsAreGivenInTcx_UnifiedTrackPointShouldRetreiveIt()不并显示我的问题。
I know, it is hard to explain and put all needed classes into comment - so I share my current status here and just write that: GetUnifiedData_WhenTrackPointsAreGivenInTcx_UnifiedTrackPointShouldRetreiveIt() is not passing and shows my problem.
<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>
推荐答案
问题是您的数据模型错误。在下面的摘录中,您将在 Lap
元素下面看到两个 Track
元素:
The problem is that your data model is wrong. In the below excerpt, you will see two Track
elements below the Lap
element:
<?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>
但是,在您的数据模型中,跟踪
为 Lap
的单例属性,其中包含 TrackPoint_t
条目的数组。当 XmlSerializer
遇到多个 Track
元素时,它将无法反序列化它们。
However, in your data model Track
is a singleton property of Lap
containing an array of TrackPoint_t
entries. When XmlSerializer
encounters more than one Track
elements it fails to deserialize them.
因此,您的数据模型需要如下。引入一个中间类 Track_t
:
Thus your data model needs to be as follows. Introduce an intermediate class 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 $
You will also need to modify Course_t
in the same way.
xsd
确实指定了类型 Track_t
,并且 ActivityLap_t
可以包含无限数量的 Track
这种类型的元素,因此以某种方式将XSD错误地转换为类:
The xsd
does specify the existence of a type Track_t
and that ActivityLap_t
can contain an unbounded number of Track
elements of this type, so somehow the XSD was transformed into classes incorrectly:
<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>
这篇关于从XSD创建的类的反序列化并不包含所有数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!