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.min
和 Bar.max
被定义为 int
s,而 "Players[1].Constants.Data.Life"
看起来一点也不像 int。
我有一个 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.min
和 Bar.max
被定义为 int
s,而 "Players[1].Constants.Data.Life"
看起来一点也不像 int。