xsd.exe 生成了 XML 反序列化器 returns 空

xsd.exe generated XML deserializer returns null

我有一个 XSD 与 xsd.exe 一起使用来生成 XML 反序列化器。但是,在运行时,它不会反序列化 Bar 或 Timer 定义。

XSD相关部分如下:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://schemas.koboltentertainment.com"
    elementFormDefault="qualified"
    xmlns="http://schemas.koboltentertainment.com"
    xmlns:mstns="http://schemas.koboltentertainment.com"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <!-- Bar Definition -->
  <xs:complexType name="Bar">
    <xs:sequence>
      <xs:element name="MaskAnim" type="Anim" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" />
    <xs:attribute name="anim" type="xs:positiveInteger" />
    <xs:attribute name="recoverAnim" type="xs:positiveInteger" />
    <xs:attribute name="min" type="xs:int" />
    <xs:attribute name="max" type="xs:int" />
    <xs:attribute name="valueBind" type="xs:string" />
    <xs:attribute name="pos" type="vector" />
    <xs:attribute name="layer" type="xs:byte" />
    <xs:attribute name="width" type="xs:int" />
  </xs:complexType>

  <!-- CONTAINAZ -->
  <xs:element name="Containers">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Container" minOccurs="1" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- Container -->
  <xs:element name="Container">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Bar" type="Bar" minOccurs="1" maxOccurs="1" />
      </xs:sequence>
      <xs:attribute name="name" type="xs:string"/>
      <xs:attribute name="id" type="xs:positiveInteger" />
      <xs:attribute name="pos" type ="vector"/>
      <xs:attribute name="layer" type="xs:byte" />
      <xs:attribute name="anim" type="xs:positiveInteger" />
      <xs:attribute name="alignment" type="alignment" />
    </xs:complexType>
  </xs:element>

生成的部分 class 如下所示:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.koboltentertainment.com")]
public partial class Bar {
    // data members, etc.
}

最后,XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<UI xmlns="http://schemas.koboltentertainment.com">
    <Info>
        <Version>1.0.0.0</Version>
        <LocalCoord>640,480</LocalCoord>
    </Info>

    <Files>
        <Sprite>life.sff</Sprite>
        <Anim>life.air</Anim>
    </Files>

    <!-- HUD implementation. All positions are relative to the top-left of the screen. -->
    <HUD>
        <Containers>
            <!-- P1 LifeBar -->
            <Container name="P1LifeBar" pos="6,69" layer="201" alignment="Left" anim="0" id="11">
                <!-- Note here how we set the AnimSource element to self and the SFFSource to Player[0] (P1)'s SFF.
                     This means the animation should use P1's sprite data, but use our animation data. This is
                     similar to ChangeAnim2 in character code. -->
                <Anim name="P1Portrait" pos="12,0" layer="199" anim="9000" id="12">
                    <!-- Valid Values for AnimSource and SFFSource: self, Player[x] -->
                    <AnimSource>self</AnimSource>
                    <SFFSource>Players[0]</SFFSource>
                </Anim>

                <!-- We set the bar min and max according to P1's constants. We bind it to P1's Life property. -->
                <Bar min="0" max="Players[0].Constants.Data.Life" valueBind="Players[0].Life" pos="6,69" layer="200"
                     width="263" anim="1" recoverAnim="2" id="13">
                    <Mask anim="10"/>
                </Bar>

                <!-- Here we have our first Text. It binds to P1's Name.-->
                <Text font="Aqua Grotesque" pos="24,56" valueBind="Players[0].Name" alignment="Left"/>
            </Container>

            <!-- P2 LifeBar -->
            <Container name="P2LifeBar" pos="6,69" layer="201" alignment="Right" anim="3" id="14">
                <Anim name="P2Portrait" pos="614,0" layer="199" anim="9001" id="15">
                    <AnimSource>self</AnimSource>
                    <SFFSource>Players[1]</SFFSource>
                </Anim>
                <Bar min="0" max="Players[1].Constants.Data.Life" valueBind="Players[1].Life" pos="6,69" layer="200"
                     width="263" anim="4" recoverAnim="5" id="16">
                    <Mask anim="10"/>
                </Bar>
                <Text font="Aqua Grotesque" pos="400,56" valueBind="Players[0].Name" alignment="Right"/>
            </Container>
        </Containers>

        <!-- Timer. It's like Text with additional timer options, such as whether or not it is affected by Turbo. -->
        <Timer font="timer.xnb" pos="312,32" turboTime="false" valueBind="RoundTime">
            <!-- These are the times that are valid for this timer. These will be selectable from Options menu. -->
            <ValidTimes>
                <TimeOption>0</TimeOption>
                <TimeOption>30</TimeOption>
                <TimeOption>60</TimeOption>
                <TimeOption>90</TimeOption>
            </ValidTimes>
            <TicksPerCount>60</TicksPerCount>
        </Timer>
    </HUD>
</UI>

Containers、Container 及其包含的大部分内容都已正确反序列化,但 Bar 没有。它在运行时总是 returns null。为什么不反序列化?

我对 xsd 一点都不熟悉。然而,当某些东西没有反序列化时,通常是因为数据无效。

在这种情况下,我猜是因为 Bar.minBar.max 被定义为 ints,而 "Players[1].Constants.Data.Life" 看起来一点也不像 int。