从XSD创建的类的反序列化并不包含所有数据 [英] Deserialization to classes created from XSD does not contain all data

查看:102
本文介绍了从XSD创建的类的反序列化并不包含所有数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将包含运动数据的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆