从使用 XSD.exe 生成的 XML 中反序列化类
Posted
技术标签:
【中文标题】从使用 XSD.exe 生成的 XML 中反序列化类【英文标题】:Deserializing classes from XML generated using XSD.exe 【发布时间】:2011-02-15 10:46:00 【问题描述】:我有从 .xsd 生成的类(使用 xsd.exe),我可以很好地序列化它,但是当我尝试反序列化它时,我得到了错误:
"<XMLLanguages xmlns='http://tempuri.org/XMLLanguages.xsd'> was not expected."
我已经搜索了几个小时,发现大多数人的问题在于没有在他们的 xsd/xml 中声明名称空间,没有在他们的类中定义名称空间等,但我找不到解决我的问题的方法。
这里是相关类的代码 sn-ps。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLLanguages"
targetNamespace="http://tempuri.org/XMLLanguages.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLLanguages.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="XMLLanguages">
<xs:complexType>
<xs:sequence>
<xs:element name="Tier" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="L" minOccurs="1" maxOccurs="unbounded" type="Language"/>
</xs:sequence>
<xs:attribute name="TierID" type="xs:int"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Language">
<xs:sequence>
<xs:element name="LangID" type="xs:int"/>
<xs:element name="Tier" type="xs:int"/>
<xs:element name ="Name" type="xs:string"/>
</xs:sequence>
<xs:attribute name ="PassRate" type="xs:int"/>
</xs:complexType>
</xs:schema>
还有班级:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://tempuri.org/XMLLanguages.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/XMLLanguages.xsd", IsNullable = false)]
public partial class XMLLanguages
private List<XMLLanguagesTier> tierField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Tier")]
public List<XMLLanguagesTier> Tiers
get
return this.tierField;
set
this.tierField = value;
以及导致错误的 XML 中的一行:
<XMLLanguages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/XMLLanguages.xsd">
反序列化方法:
public static object Deserialize(XmlDocument xml, Type type)
XmlSerializer s = new XmlSerializer(type);
string xmlString = xml.OuterXml.ToString();
byte[] buffer = ASCIIEncoding.UTF8.GetBytes(xmlString);
MemoryStream ms = new MemoryStream(buffer);
XmlReader reader = new XmlTextReader(ms);
Exception caught = null;
try
object o = s.Deserialize(reader);
return o;
catch (Exception e)
caught = e;
finally
reader.Close();
if (caught != null)
throw caught;
return null;
【问题讨论】:
你能告诉我们sn-p的代码实际上做了反序列化吗?您是否在反序列化代码中关注并包含 XML 命名空间“tempuri.org/XMLLanguages.xsd”?? 【参考方案1】:我使用下面的代码,它工作正常。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Report"
targetNamespace="http://www.xyz.com/Report.xsd"
elementFormDefault="qualified"
xmlns="http://www.xyz.com/Report.xsd"
xmlns:mstns="http://www.xyz.com/Report.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Report">
<xs:complexType>
...
我将 xsd.exe 与 /n:xyz 命名空间选项一起使用。
这似乎工作正常,所以我认为您的问题一定是 tempuri.org 域名。
希望对你有所帮助。
理查德。
【讨论】:
tempuri 域是 VS2010 中 xsd 文件的默认域,我用新的 xml 文件尝试了另一个域,错误相同,保存新域。 我认为问题可能是这些类未定义为与 xml 位于同一命名空间中,因此将命名空间更改为全部相同。还是不行。但是,XmlDocument 的 NamespaceURI 属性是“”,我不确定这是否是问题所在。【参考方案2】:您需要从根中移除 targetNamespace 属性,并在 XMLLanguages 节点之前添加以下节点:
<xs:import namespace="http://www.w3.org/2001/XMLSchema"/>
以上将让您反序列化,但我感觉到其他问题即将出现。您面临的问题是,当您定义多个复杂类型时,您不能使用 targetNamespace 属性——欢迎来到模式命名空间地狱......
【讨论】:
以上是关于从使用 XSD.exe 生成的 XML 中反序列化类的主要内容,如果未能解决你的问题,请参考以下文章
使用 WCF 将类序列化为 xsd.exe 生成的 JSON
使用 xsd.exe 或 svcutil.exe 对 UWP 和 Xamarin 进行 C# XML 序列化
在不修改 C# XSD 类的情况下向 XML 序列化添加前缀和命名空间