gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 04:04:19 25 4
gpt4 key购买 nike

我正在尝试反序列化以下 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 的Paste XML as Classes 功能生成了类。(使用 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: 'There is an error in XML document (33, 14).'

Inner Exception

InvalidOperationException: The specified type was not recognized: name='genericDrug', namespace='http://webservice.sirkb/', at 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?

最佳答案

您需要更改 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 的定义,您会发现它的类型在 namespace 别名“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;
}
}
}

关于C# 无法反序列化包含 xsi :type 的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52775320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com