如何将 Microsoft xsd.exe 与 TrainingCenterDatabasev2 架构一起使用?

How to use Microsoft xsd.exe with TrainingCenterDatabasev2 Schema?

我有 TCX 练习文件,这些文件是使用 https://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd 中的架构编写的。多年来,我一直将它们与 Java 和 JAXB 一起使用。我正在尝试编写一个 C# 应用程序来做同样的事情。进展不顺利。我可以使用 Visual Studio 提供的 xsd.exe 生成 C# 类。但是,它们对我没有意义,不能用于反序列化我的 TCX 文件。

TCX 文件的基本结构(至少是我感兴趣的部分)是它们有许多 Activities,其中包含许多 Laps,其中包含许多 Tracks,其中包含许多 Trackpoints。 Trackpoints 以纬度、经度和心率作为主要关注项。

xsd-生成的 C# 类 有一个 Activity_t[]、一个 ActivityLap_t[] 和一个 Trackpoint_t[][]。没有 Track_t[] 并且字符串 Track_t 没有出现在文件中,即使它在 .xsd 中,例如在 Lap and Track 的这个摘录中。

<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"/>
            <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>

我不明白如何处理 [][] 也不知道为什么会生成它。如前所述,它无法解析。

error CS0030: Cannot convert type 'TrainingCenterDatabaseV2.Trackpoint_t[] to TrainingCenterDatabaseV2.Trackpoint_t.

(我使用的命名空间是TrainingCenterDatabaseV2。)

这是用于反序列化的代码:

private const string NS_TrainingCenterDatabase_v2 = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2";

XmlSerializer xmlSerializer = new XmlSerializer(typeof(TrainingCenterDatabase_t),
                NS_TrainingCenterDatabase_v2);
FileStream fs = new FileStream(fileName, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
TrainingCenterDatabase_t tcx = (TrainingCenterDatabase_t)xmlSerializer.Deserialize(reader);

不知道该去哪里,我尝试了 Visual Studio 插件,xsd2code++。这会生成具有 List、List 和 List 的合理 C# 类。它也没有Track_t,这似乎有些多余。

但是,同样解析失败。我认为与 xsd.exe 生成的注释相比,这里的问题与它生成的注释缺少有关。我相信问题在于它无法处理没有这些注释的命名空间,但我没有看到设置选项来解决这个问题的方法。如前所述,我没有使用 C# 进行反序列化的经验。对于我目前的目的,我已经实现了使用 XDocument 而不是反序列化来读取 TCX 文件。但是,我很好奇为什么我尝试的方法不起作用,特别是因为 xsd.exe 已经存在很长时间了。

提前致谢。

这似乎是 xsd.exe 工具本身的错误。我建议使用 LinqToXsd(需要 .NET Core 2.1),这是 Microsoft 开发的另一种使用 XSD 访问 XML 数据的技术;它也比 xsd.exe 更先进,并且在我的快速测试中似乎可以毫无问题地完全处理上述 Garmin 培训中心数据库模式。

此外,如果您无法在您的计算机上安装 .NET Core,您可以使用此 nuget package 代替。 .NET Core 版本需要 .NET Core 2.1 才能实际生成代码,但生成的代码可用于面向 .NET Framework 4.6.2 及更高版本的应用程序。