从使用 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 序列化

如何将 XML 映射到 C# 对象

在不修改 C# XSD 类的情况下向 XML 序列化添加前缀和命名空间

从XSD文件生成的类实例中获取XML字符串XSD.exe文件

如何将模型(从 xsd.exe 构建)序列化为 XmlDocument?