我一直在尝试使用xsd.exe中的模式生成的类来反序列化C#中的xml文件。不幸的是,只有部分文件被正确反序列化,其余部分由于我无法解决的原因而返回为null。
我的流程如下: 从生成C#代码的myschema.xsd文件开始:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mc="myschema:common" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ttl="http://www.myuri.org/myschema" targetNamespace="http://www.myuri.org/myschema" elementFormDefault="qualified" attributeFormDefault="unqualified">
并且导入的parentschema.xsd文件是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:mc="myschema:common" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="myschema:common" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="toplevel">
<xs:complexType>
<xs:sequence>
<xs:element ref="mc:toplevel_header" minOccurs="0"/>
<xs:element ref="mc:body"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="toplevel_header">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:anyURI"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="body" type="mc:body" abstract="true"/>
<xs:complexType name="body">
<xs:attribute name="id" type="xs:ID" use="required"/>
</xs:complexType>
<xs:element name="Entity" type="mc:Entity" abstract="true"/>
<xs:complexType name="Entity" abstract="true">
<xs:attribute name="href" type="xs:anyURI" use="optional"/>
</xs:complexType>
</xs:schema>
我将以上两个架构文件传递给xsd.exe:
>xsd.exe /c myschema.xsd parentschema.xsd
生成myschema_parentschema.cs文件
要测试它我正在尝试反序列化一个示例xml文件:
<?xml version=\"1.0\" encoding="UTF-8"?>
<toplevel version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="myschema:common"
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd">
<toplevel_header>
<name>MyName</name>
</toplevel_header>
<body id="body_1"
xmlns="http://www.myuri.org/schema"
xmlns:mc="myschema:common"
xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd">
<Foo href="http://www.google.com">
</Foo>
</body>
</toplevel>
我将传递给以下XmlSerializer代码,其中reader是上述xml文件的XmlReader:
XmlSerializer xs = new XmlSerializer ( typeof ( toplevel ) );
object deserializedObject = xs.Deserialize( reader );
toplevel fooBar = (toplevel)deserializedObject;
Assert.AreEqual( "MyName", fooBar.toplevel_header.name ); //passes OK
Assert.IsNotNull( fooBar.body ); //<--------FAIL
为什么反序列化对象具有null body属性,如何让它正确地反序列化Foo元素?
答案 0 :(得分:0)
你的parentschema.xsd中有一个拼写错误。您正在为body标记提前关闭<xs:element>
标记:
<xs:element name="body" type="mc:body" abstract="true"/>
您还将主体定义为抽象,我认为这是一个错误(如果我正确地阅读XML)。
整个定义(基于您的XML)应该类似于:
<xs:element name="body" type="mc:body" abstract="true">
<xs:complexType>
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:sequence>
<xs:element type="Foo" type="xs:anyURI" />
</xs:sequence>
</xs:complexType>
</xs:element>
答案 1 :(得分:0)
我按照与您相同的步骤操作,看起来您的架构和要反序列化的XML文件不匹配。这是我做的:
static void Main(string[] args)
{
var xs = new XmlSerializer(typeof(toplevel));
// test saving to xml first...
var tl = new toplevel();
tl.toplevel_header = new toplevel_header();
tl.toplevel_header.name = "MyName";
tl.body = new body();
tl.body.id = "body id...";
// output to console first...
var cw = Console.OpenStandardOutput();
xs.Serialize(cw, tl);
Console.WriteLine();
Console.WriteLine();
// save to file...
var fw = File.CreateText("test.xml");
xs.Serialize(fw, tl);
fw.Close();
// read file...
var fr = File.Open("test.xml", FileMode.Open, FileAccess.Read);
var obj = xs.Deserialize(fr);
var fooBar = (toplevel)obj;
Console.WriteLine(fooBar.toplevel_header.name);
Console.WriteLine(fooBar.body.id);
Console.ReadLine();
}
序列化程序生成的XML是:
<?xml version="1.0" encoding="utf-8"?>
<toplevel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="myschema:common">
<toplevel_header>
<name>MyName</name>
</toplevel_header>
<body id="body id..." />
</toplevel>
XML显然与您正在使用的输入XML文件不匹配...希望这对您有所帮助!
答案 2 :(得分:0)
看看你的样本xml我发现了一个不一致的地方,这就是为什么XmlSerializer没有提出你期望的结果:
<toplevel version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
***xmlns="myschema:common"***
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd">
<toplevel_header>
<name>MyName</name>
</toplevel_header>
<body id="body_1"
***xmlns="http://www.myuri.org/schema"***
***xmlns:mc="myschema:common"***
xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd">
<Foo href="http://www.google.com">
</Foo>
</body>
</toplevel>
在您的顶层元素中,您定义的是xmlns =“myschema:common”,但在您的body元素中,您定义的是xmlns =“http://www.myuri.org/schema”,下一行是xmlns:mc = “MYSCHEMA:普通”。这意味着正文内部的Foo元素位于不同的名称空间下,并且XmlSerializer将找不到该元素。当我删除body元素中的xmlns声明并将xmlns:mc声明更改为xmlns时,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<toplevel version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="myschema:common"
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd">
<toplevel_header>
<name>MyName</name>
</toplevel_header>
<body id="body_1"
xmlns="myschema:common"
xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd">
<Foo href="http://www.google.com">
</Foo>
</body>
</toplevel>
根据指示调整了样本xml,XmlSerializer在其中创建了一个非空体的顶层对象。