由于命名空间而无法反序列化 xml

Posted

技术标签:

【中文标题】由于命名空间而无法反序列化 xml【英文标题】:Failed deserializing xml due to namespaces 【发布时间】:2021-07-02 01:09:07 【问题描述】:

我有以下要反序列化为 c# 类的 xml:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.s1.com/info/" xmlns:types="http://www.s1.com/info/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <tns:SessionInfo>
      <SessionId xsi:type="xsd:string">string</SessionId>
    </tns:SessionInfo>
  </soap:Header>
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:LoginResponse>
      <Result xsi:type="xsd:boolean">boolean</Result>
    </tns:LoginResponse>
  </soap:Body>
</soap:Envelope>

我正在使用以下类来反序列化 xml:

        public class SessionId
        

            [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
            public string Type  get; set; 

            [XmlText]
            public string Text  get; set; 
        

        [XmlRoot(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
        public class SessionInfo
        

            [XmlElement(ElementName = "SessionId")]
            public SessionId SessionId  get; set; 

            [XmlAttribute(AttributeName = "id", Namespace = "")]
            public string Id  get; set; 

            [XmlText]
            public string Text  get; set; 
        

        [XmlRoot(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Header
        

            [XmlElement(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
            public SessionInfo SessionInfo  get; set; 
        


        [XmlRoot(ElementName = "Result", Namespace = "")]
        public class Result
        

            [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
            public string Type  get; set; 

            [XmlText]
            public string Text  get; set; 
        

        [XmlRoot(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
        public class LoginResponse
        

            [XmlElement(ElementName = "Result")]
            public Result Result  get; set; 
        

        [XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Body
        

            [XmlElement(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
            public LoginResponse LoginResponse  get; set; 

            [XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public string EncodingStyle  get; set; 

            [XmlText]
            public string Text  get; set; 
        

        [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Envelope
        

            [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Header Header  get; set; 

            [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Body Body  get; set; 

            [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsi  get; set; 

            [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsd  get; set; 

            [XmlAttribute(AttributeName = "soapenc", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soapenc  get; set; 

            [XmlAttribute(AttributeName = "tns", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Tns  get; set; 

            [XmlAttribute(AttributeName = "types", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Types  get; set; 

            [XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soap  get; set; 

            [XmlText]
            public string Text  get; set; 
        

问题是 SessionId 元素没有被反序列化,我假设是由于命名空间不匹配。我尝试使用空字符串作为命名空间,但这也不起作用,因为它在反序列化过程中无法被识别。

非常感谢您对问题的任何见解。谢谢!

【问题讨论】:

添加命名空间:[XmlElement(ElementName = "SessionId", Namespace = "s1.com/info/")] @jdweng 我试过了,但好像不行。 将 SessionId 设为字符串:[XmlElement(ElementName = "SessionId", Namespace = "")] public string SessionId get;放; 【参考方案1】:

首先,SessionId 有错误的命名空间。它从父级继承,您需要通过将其设置为空字符串来明确指定它没有。

其次,xsi:type 有特殊含义,你不应该尝试反序列化它。它用于指示元素的内容类型 - 在本例中为 string - 并将由序列化程序使用。这意味着这是许多可接受的类型之一。最简单的定义方法是使用object

将它们放在一起,这应该可以工作:

[XmlElement(ElementName = "SessionId", Namespace = "")]
public object SessionId  get; set; 

SessionId 应该包含一个 string 对象,其值为 string

我还要注意其他一些小事:

不应将所有命名空间绑定(例如 Xsd)指定为模型的一部分。这比此模型低级别,将由序列化程序处理。 你只需要在根目录下XmlRoot 你不需要XmlText没有任何文本的属性 您需要对上面进行类似的更改以反序列化Result ElementNameAttributeName 将默认为属性的名称,因此如果您需要,则不必指定这些

考虑到这一点,这个模型应该可以工作:

public class SessionInfo

    [XmlElement(Namespace = "")]
    public object SessionId  get; set; 


public class Header

    [XmlElement(Namespace = "http://www.s1.com/info/")]
    public SessionInfo SessionInfo  get; set; 


public class LoginResponse

    [XmlElement(Namespace = "")]
    public object Result  get; set; 


public class Body

    [XmlElement(Namespace = "http://www.s1.com/info/")]
    public LoginResponse LoginResponse  get; set; 

    [XmlAttribute("encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/", Form = XmlSchemaForm.Qualified)]
    public string EncodingStyle  get; set; 


[XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope

    [XmlElement]
    public Header Header  get; set; 

    [XmlElement]
    public Body Body  get; set; 

您可以看到一个工作演示 here。我对源 XML 进行了一项更改 - 我将 Result 值从 boolean 更改为 true,否则您将收到异常,因为 boolean 不是该类型的有效值。

【讨论】:

非常感谢您不仅提供了一个有效的答案,还感谢您的解释,我还在学习,所以它对我非常有用!

以上是关于由于命名空间而无法反序列化 xml的主要内容,如果未能解决你的问题,请参考以下文章

C# 在忽略命名空间的同时反序列化 xml

Jackson XML - 使用命名空间前缀反序列化 XML

C# 使用多个可能的命名空间反序列化 xml

反序列化自定义 XML 时出现 InvalidOperationException(缺少命名空间)

如何在 .NET 中的反序列化期间指定 XML 序列化属性以支持命名空间前缀?

包含命名空间的xml反序列化 (1.7环境下)