C#无法反序列化包含xsi:type

时间:2018-10-12 08:25:12

标签: c# xml xml-deserialization

我正在尝试反序列化以下XML

<?xml version="1.0" encoding="UTF-8"?>
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
  <EnvelopeVersion>2.0</EnvelopeVersion>
  <Header>
    <MessageDetails>
      <Class>DRUG_DATA</Class>
      <Qualifier>response</Qualifier>
      <Function>submit</Function>
      <CorrelationID>BD694DAAA26AA6068EAAAE5C7746CE54</CorrelationID>
      <Transformation>XML</Transformation>
    </MessageDetails>
    <SenderDetails>
      <IDAuthentication>
        <SenderID />
        <Authentication>
          <Method />
          <Role />
          <Value />
        </Authentication>
      </IDAuthentication>
    </SenderDetails>
  </Header>
  <GovTalkDetails>
    <Keys>
      <Key Type="SpokeName" />
    </Keys>
  </GovTalkDetails>
  <Body>
    <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
      <S:Body>
        <ns2:getGenericDrugsResponse xmlns:ns2="http://webservice.sirkb/">
          <return>
            <DRUG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:genericDrug">
              <GENERIC_DRUG_ID>147</GENERIC_DRUG_ID>
              <GENERIC_DRUG_NAME>Amoxicilline 125mg/5ml - 60ml</GENERIC_DRUG_NAME>
            </DRUG>
            <DRUG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:genericDrug">
              <GENERIC_DRUG_ID>149</GENERIC_DRUG_ID>
              <GENERIC_DRUG_NAME>Amoxicilline 250mg/5ml - 60ml</GENERIC_DRUG_NAME>
            </DRUG>            
            <DRUG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:genericDrug">
              <DOSAGE>10mg/5ml</DOSAGE>
              <GENERIC_DRUG_ID>2312</GENERIC_DRUG_ID>
              <GENERIC_DRUG_NAME>Vinorelbine (as vinorelbine tartrate)</GENERIC_DRUG_NAME>
              <PHARMACEUTICAL_FORM>concentrate for solution for infusion</PHARMACEUTICAL_FORM>
            </DRUG>
            <DRUG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:genericDrug">
              <DOSAGE>100 u/ml (approximately 0.58mg)</DOSAGE>
              <GENERIC_DRUG_ID>2313</GENERIC_DRUG_ID>
              <GENERIC_DRUG_NAME>Laronidase</GENERIC_DRUG_NAME>
              <PHARMACEUTICAL_FORM>concentrate for solution for infusion</PHARMACEUTICAL_FORM>
            </DRUG>
            <RETURN_STATUS>SUCCESS</RETURN_STATUS>
          </return>
        </ns2:getGenericDrugsResponse>
      </S:Body>
    </S:Envelope>
  </Body>
</GovTalkMessage>

我已经通过Visual Studio 2017的粘贴XML作为类功能生成了这些类。(使用xsd.exe相同)我没有更改生成的类。

它们具有以下形式:

// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope", IsNullable = false)]
public partial class GovTalkMessage
{

    private decimal envelopeVersionField;

    private GovTalkMessageHeader headerField;

    private GovTalkMessageGovTalkDetails govTalkDetailsField;

    private GovTalkMessageBody bodyField;

    /// <remarks/>
    public decimal EnvelopeVersion
    {
        get
        {
            return this.envelopeVersionField;
        }
        set
        {
            this.envelopeVersionField = value;
        }
    }

    /// <remarks/>
    public GovTalkMessageHeader Header
    {
        get
        {
            return this.headerField;
        }
        set
        {
            this.headerField = value;
        }
    }

    /// <remarks/>
    public GovTalkMessageGovTalkDetails GovTalkDetails
    {
        get
        {
            return this.govTalkDetailsField;
        }
        set
        {
            this.govTalkDetailsField = value;
        }
    }

    /// <remarks/>
    public GovTalkMessageBody Body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageHeader
{

    private GovTalkMessageHeaderMessageDetails messageDetailsField;

    private GovTalkMessageHeaderSenderDetails senderDetailsField;

    /// <remarks/>
    public GovTalkMessageHeaderMessageDetails MessageDetails
    {
        get
        {
            return this.messageDetailsField;
        }
        set
        {
            this.messageDetailsField = value;
        }
    }

    /// <remarks/>
    public GovTalkMessageHeaderSenderDetails SenderDetails
    {
        get
        {
            return this.senderDetailsField;
        }
        set
        {
            this.senderDetailsField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageHeaderMessageDetails
{

    private string classField;

    private string qualifierField;

    private string functionField;

    private string correlationIDField;

    private string transformationField;

    /// <remarks/>
    public string Class
    {
        get
        {
            return this.classField;
        }
        set
        {
            this.classField = value;
        }
    }

    /// <remarks/>
    public string Qualifier
    {
        get
        {
            return this.qualifierField;
        }
        set
        {
            this.qualifierField = value;
        }
    }

    /// <remarks/>
    public string Function
    {
        get
        {
            return this.functionField;
        }
        set
        {
            this.functionField = value;
        }
    }

    /// <remarks/>
    public string CorrelationID
    {
        get
        {
            return this.correlationIDField;
        }
        set
        {
            this.correlationIDField = value;
        }
    }

    /// <remarks/>
    public string Transformation
    {
        get
        {
            return this.transformationField;
        }
        set
        {
            this.transformationField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageHeaderSenderDetails
{

    private GovTalkMessageHeaderSenderDetailsIDAuthentication iDAuthenticationField;

    /// <remarks/>
    public GovTalkMessageHeaderSenderDetailsIDAuthentication IDAuthentication
    {
        get
        {
            return this.iDAuthenticationField;
        }
        set
        {
            this.iDAuthenticationField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageHeaderSenderDetailsIDAuthentication
{

    private object senderIDField;

    private GovTalkMessageHeaderSenderDetailsIDAuthenticationAuthentication authenticationField;

    /// <remarks/>
    public object SenderID
    {
        get
        {
            return this.senderIDField;
        }
        set
        {
            this.senderIDField = value;
        }
    }

    /// <remarks/>
    public GovTalkMessageHeaderSenderDetailsIDAuthenticationAuthentication Authentication
    {
        get
        {
            return this.authenticationField;
        }
        set
        {
            this.authenticationField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageHeaderSenderDetailsIDAuthenticationAuthentication
{

    private object methodField;

    private object roleField;

    private object valueField;

    /// <remarks/>
    public object Method
    {
        get
        {
            return this.methodField;
        }
        set
        {
            this.methodField = value;
        }
    }

    /// <remarks/>
    public object Role
    {
        get
        {
            return this.roleField;
        }
        set
        {
            this.roleField = value;
        }
    }

    /// <remarks/>
    public object Value
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageGovTalkDetails
{

    private GovTalkMessageGovTalkDetailsKeys keysField;

    /// <remarks/>
    public GovTalkMessageGovTalkDetailsKeys Keys
    {
        get
        {
            return this.keysField;
        }
        set
        {
            this.keysField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageGovTalkDetailsKeys
{

    private GovTalkMessageGovTalkDetailsKeysKey keyField;

    /// <remarks/>
    public GovTalkMessageGovTalkDetailsKeysKey Key
    {
        get
        {
            return this.keyField;
        }
        set
        {
            this.keyField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageGovTalkDetailsKeysKey
{

    private string typeField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Type
    {
        get
        {
            return this.typeField;
        }
        set
        {
            this.typeField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class GovTalkMessageBody
{

    private Envelope envelopeField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope")]
    public Envelope Envelope
    {
        get
        {
            return this.envelopeField;
        }
        set
        {
            this.envelopeField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
public partial class Envelope
{

    private EnvelopeBody bodyField;

    /// <remarks/>
    public EnvelopeBody Body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeBody
{

    private getGenericDrugsResponse getGenericDrugsResponseField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://webservice.sirkb/")]
    public getGenericDrugsResponse getGenericDrugsResponse
    {
        get
        {
            return this.getGenericDrugsResponseField;
        }
        set
        {
            this.getGenericDrugsResponseField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://webservice.sirkb/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://webservice.sirkb/", IsNullable = false)]
public partial class getGenericDrugsResponse
{

    private @return returnField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
    public @return @return
    {
        get
        {
            return this.returnField;
        }
        set
        {
            this.returnField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope", IsNullable = false)]
public partial class @return
{

    private returnDRUG[] dRUGField;

    private string rETURN_STATUSField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("DRUG")]
    public returnDRUG[] DRUG
    {
        get
        {
            return this.dRUGField;
        }
        set
        {
            this.dRUGField = value;
        }
    }

    /// <remarks/>
    public string RETURN_STATUS
    {
        get
        {
            return this.rETURN_STATUSField;
        }
        set
        {
            this.rETURN_STATUSField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class returnDRUG
{

    private string dOSAGEField;

    private ushort gENERIC_DRUG_IDField;

    private string gENERIC_DRUG_NAMEField;

    private string pHARMACEUTICAL_FORMField;

    /// <remarks/>
    public string DOSAGE
    {
        get
        {
            return this.dOSAGEField;
        }
        set
        {
            this.dOSAGEField = value;
        }
    }

    /// <remarks/>
    public ushort GENERIC_DRUG_ID
    {
        get
        {
            return this.gENERIC_DRUG_IDField;
        }
        set
        {
            this.gENERIC_DRUG_IDField = value;
        }
    }

    /// <remarks/>
    public string GENERIC_DRUG_NAME
    {
        get
        {
            return this.gENERIC_DRUG_NAMEField;
        }
        set
        {
            this.gENERIC_DRUG_NAMEField = value;
        }
    }

    /// <remarks/>
    public string PHARMACEUTICAL_FORM
    {
        get
        {
            return this.pHARMACEUTICAL_FORMField;
        }
        set
        {
            this.pHARMACEUTICAL_FORMField = value;
        }
    }
}

我收到以下错误:

  

System.InvalidOperationException:“ XML文档中存在错误(33、14)。”

     

内部异常

     

InvalidOperationException:无法识别指定的类型:   名称='genericDrug',名称空间='http://webservice.sirkb/',位于http://www.govtalk.gov.uk/CM/envelope'>。

我从this线程中注意到,如果我从XML文件中删除xsi:type="ns2:genericDrug",则可以反序列化XML。我无法修改XML,因为它是我对请求的响应。在XML上执行字符串替换不是一个好习惯,因此我正在寻找更好的解决方案。

这可能是来自this one的重复问题,但是由于我无法解决问题,因此我将其再次发布,因为很难在评论部分获得帮助。

基于上述问题,我试图更改public partial class returnDRUG的注释

来自

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]

[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.w3.org/2001/XMLSchema-instance", TypeName = "genericDrug")]

但仍然无法解析XML。

解析代码很简单

var deserializer = new XmlSerializer(typeof(GovTalkMessage));
TextReader textReader = new StreamReader("drug.xml"); //saved response in file for simplicity
GovTalkMessage response;
response = (GovTalkMessage)deserializer.Deserialize(textReader);
textReader.Close();

如何对GovTalkMessage对象中的XML进行反序列化?

1 个答案:

答案 0 :(得分:0)

您需要更改returnDRUG类的修饰

从此

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
public partial class returnDRUG

对此

[System.Xml.Serialization.XmlTypeAttribute(TypeName = "genericDrug", Namespace = "http://webservice.sirkb/")]
public partial class returnDRUG

将其类型指定为“ genericDrug”,关键点是,将其名称空间更正为“ http://webservice.sirkb/

我刚刚使用了您的代码,并使用此更改设法取消了序列化。

解释是,如果您看一下DRUG的定义,您会发现它的类型在名称空间别名“ ns2”中定义为“ genericDRUG”

<DRUG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:genericDrug">

如果您查看ns2别名的定义,您会发现它是“ http://webservice.sirkb/

<ns2:getGenericDrugsResponse xmlns:ns2="http://webservice.sirkb/">

一些附加功能可以防止 DRUG 对象的默认值

returnDrug类的每个属性都应具有名称空间http://www.govtalk.gov.uk/CM/envelope

完整的类应具有以下形式:

[System.Xml.Serialization.XmlTypeAttribute(TypeName = "genericDrug", Namespace = "http://webservice.sirkb/")]
public partial class returnDRUG
{

    private string dOSAGEField;

    private ushort gENERIC_DRUG_IDField;

    private string gENERIC_DRUG_NAMEField;

    private string pHARMACEUTICAL_FORMField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
    public string DOSAGE
    {
        get
        {
            return this.dOSAGEField;
        }
        set
        {
            this.dOSAGEField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
    public ushort GENERIC_DRUG_ID
    {
        get
        {
            return this.gENERIC_DRUG_IDField;
        }
        set
        {
            this.gENERIC_DRUG_IDField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
    public string GENERIC_DRUG_NAME
    {
        get
        {
            return this.gENERIC_DRUG_NAMEField;
        }
        set
        {
            this.gENERIC_DRUG_NAMEField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.govtalk.gov.uk/CM/envelope")]
    public string PHARMACEUTICAL_FORM
    {
        get
        {
            return this.pHARMACEUTICAL_FORMField;
        }
        set
        {
            this.pHARMACEUTICAL_FORMField = value;
        }
    }
}