反序列化 XML 并在 XML 文档中出错 (2, 2)

Posted

技术标签:

【中文标题】反序列化 XML 并在 XML 文档中出错 (2, 2)【英文标题】:Deserializing XML and Getting an Error in XML Document (2, 2) 【发布时间】:2021-08-28 13:28:31 【问题描述】:

我有一个正在读取的 XML 文件并试图反序列化为一个对象。我尝试时收到此错误:

System.InvalidOperationException: 'XML 文档 (2, 2) 中存在错误。' InvalidOperationException: 不是预期的。

这是 XML 文件:

<?xml version="1.0" encoding="utf-8" ?>
<ns6:ACABulkRequestTransmitterStatusDetailResponse xmlns="urn:us:gov:treasury:irs:ext:aca:air:ty20" xmlns:ns2="urn:us:gov:treasury:irs:common" xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns4="http://www.w3.org/2000/09/xmldsig#" xmlns:ns5="urn:us:gov:treasury:irs:msg:acasecurityheader" xmlns:ns6="urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest">
    <ACABulkRequestTransmitterResponse>
        <TransmissionStatusCd>Rejected</TransmissionStatusCd>
        <ns2:ReceiptId>AATS1094B-21-00008699</ns2:ReceiptId>
    </ACABulkRequestTransmitterResponse>
    <ACABulkReqTrnsmtStsRespGrpDtl>
        <ns2:BulkExchangeFile>
            <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:46834192-2caa-4016-ab11-8a48e0cbeb6c-194@urn%3Aus%3Agov%3Atreasury%3Airs%3Acommon"/>
        </ns2:BulkExchangeFile>
    </ACABulkReqTrnsmtStsRespGrpDtl>
</ns6:ACABulkRequestTransmitterStatusDetailResponse>

这是我正在使用的所有 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;

namespace ConsoleApp1

    class Program
    
        static void Main(string[] args)
        
            using (TextReader reader = File.OpenText(@"C:\Projects\Prototypes\IrsAcaClient\ConsoleApp1\XMLFile1.xml"))
            
                string xml = reader.ReadToEnd();
                var o = Deserialize<ACABulkRequestTransmitterStatusDetailResponse>(xml);
            
        

        /// <summary>
        /// deserializes the xml string into an object
        /// </summary>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string xmlString) where T : class
        
            //if the string is empty, just return null
            if (xmlString.Length <= 0)
            
                return null;
            

            //create a serializer
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            T output;
            //create the reader that the serializer will read from, passing it the string
            using (var reader = new System.IO.StringReader(xmlString))
            
                //rebuild the list object
                output = (T)serializer.Deserialize(reader);
            
            //return the list
            return output;
        
    

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest")]
    public partial class ACABulkRequestTransmitterStatusDetailResponse : object, System.ComponentModel.INotifyPropertyChanged
    

        private ACABulkRequestTransmitterResponseType aCABulkRequestTransmitterResponseField;

        private ACABulkReqTrnsmtStsRespGrpDtlType aCABulkReqTrnsmtStsRespGrpDtlField;

        private string versionField;

        public ACABulkRequestTransmitterStatusDetailResponse()
        
            this.versionField = "1.0";
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20", Order = 0)]
        public ACABulkRequestTransmitterResponseType ACABulkRequestTransmitterResponse
        
            get
            
                return this.aCABulkRequestTransmitterResponseField;
            
            set
            
                this.aCABulkRequestTransmitterResponseField = value;
                this.RaisePropertyChanged("ACABulkRequestTransmitterResponse");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20", Order = 1)]
        public ACABulkReqTrnsmtStsRespGrpDtlType ACABulkReqTrnsmtStsRespGrpDtl
        
            get
            
                return this.aCABulkReqTrnsmtStsRespGrpDtlField;
            
            set
            
                this.aCABulkReqTrnsmtStsRespGrpDtlField = value;
                this.RaisePropertyChanged("ACABulkReqTrnsmtStsRespGrpDtl");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string version
        
            get
            
                return this.versionField;
            
            set
            
                this.versionField = value;
                this.RaisePropertyChanged("version");
            
        

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            
        
    

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
    public enum TransmissionStatusCodeType
    

        /// <remarks/>
        Accepted,

        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("Accepted with Errors")]
        AcceptedwithErrors,

        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("Partially Accepted")]
        PartiallyAccepted,

        /// <remarks/>
        Rejected,

        /// <remarks/>
        Processing,

        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("Not Found")]
        NotFound,
    

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:common")]
    public partial class ErrorMessageDetailType : object, System.ComponentModel.INotifyPropertyChanged
    

        private string errorMessageCdField;

        private string errorMessageTxtField;

        private string xpathContentField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order = 0)]
        public string ErrorMessageCd
        
            get
            
                return this.errorMessageCdField;
            
            set
            
                this.errorMessageCdField = value;
                this.RaisePropertyChanged("ErrorMessageCd");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order = 1)]
        public string ErrorMessageTxt
        
            get
            
                return this.errorMessageTxtField;
            
            set
            
                this.errorMessageTxtField = value;
                this.RaisePropertyChanged("ErrorMessageTxt");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order = 2)]
        public string XpathContent
        
            get
            
                return this.xpathContentField;
            
            set
            
                this.xpathContentField = value;
                this.RaisePropertyChanged("XpathContent");
            
        

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            
        
    

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
    public partial class ACABulkRequestTransmitterResponseType : object, System.ComponentModel.INotifyPropertyChanged
    

        private TransmissionStatusCodeType transmissionStatusCdField;

        private string receiptIdField;

        private ErrorMessageDetailType errorMessageDetailField;

        private string versionField;

        public ACABulkRequestTransmitterResponseType()
        
            this.versionField = "1.0";
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order = 0)]
        public TransmissionStatusCodeType TransmissionStatusCd
        
            get
            
                return this.transmissionStatusCdField;
            
            set
            
                this.transmissionStatusCdField = value;
                this.RaisePropertyChanged("TransmissionStatusCd");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common", Order = 1)]
        public string ReceiptId
        
            get
            
                return this.receiptIdField;
            
            set
            
                this.receiptIdField = value;
                this.RaisePropertyChanged("ReceiptId");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common", Order = 2)]
        public ErrorMessageDetailType ErrorMessageDetail
        
            get
            
                return this.errorMessageDetailField;
            
            set
            
                this.errorMessageDetailField = value;
                this.RaisePropertyChanged("ErrorMessageDetail");
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string version
        
            get
            
                return this.versionField;
            
            set
            
                this.versionField = value;
                this.RaisePropertyChanged("version");
            
        

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            
        
    

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
    public partial class ACABulkReqTrnsmtStsRespGrpDtlType : object, System.ComponentModel.INotifyPropertyChanged
    

        private byte[] bulkExchangeFileField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common", DataType = "base64Binary", Order = 0)]
        public byte[] BulkExchangeFile
        
            get
            
                return this.bulkExchangeFileField;
            
            set
            
                this.bulkExchangeFileField = value;
                this.RaisePropertyChanged("BulkExchangeFile");
            
        

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            
        
    

谁能告诉我我做错了什么?谢谢。

【问题讨论】:

尝试另一个简单的 xml,同样的错误? XML 有“ACABulkRequestTransmitterStatusDetailResponse”,c# 代码有“ACABulkRequestTransmitterStatusDetailResponseType” @jdweng 感谢您的回复。我更新了原始帖子以包含您建议的更改,但是当我运行它时仍然遇到相同的错误。 【参考方案1】:

我认为这里有很多问题,更具体地说是 XML 的生成代码。

在 Visual Studio 中,我创建了一个新类并复制了您的 XML 内容并使用了编辑 -> 选择性粘贴 -> 将 XML 粘贴为类。

这是该练习生成的代码:

[System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest", IsNullable = false)]
    public partial class ACABulkRequestTransmitterStatusDetailResponse
    

        private ACABulkRequestTransmitterResponse aCABulkRequestTransmitterResponseField;

        private ACABulkReqTrnsmtStsRespGrpDtl aCABulkReqTrnsmtStsRespGrpDtlField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
        public ACABulkRequestTransmitterResponse ACABulkRequestTransmitterResponse
        
            get
            
                return this.aCABulkRequestTransmitterResponseField;
            
            set
            
                this.aCABulkRequestTransmitterResponseField = value;
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
        public ACABulkReqTrnsmtStsRespGrpDtl ACABulkReqTrnsmtStsRespGrpDtl
        
            get
            
                return this.aCABulkReqTrnsmtStsRespGrpDtlField;
            
            set
            
                this.aCABulkReqTrnsmtStsRespGrpDtlField = value;
            
        
    

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20", IsNullable = false)]
    public partial class ACABulkRequestTransmitterResponse
    

        private string transmissionStatusCdField;

        private string receiptIdField;

        /// <remarks/>
        public string TransmissionStatusCd
        
            get
            
                return this.transmissionStatusCdField;
            
            set
            
                this.transmissionStatusCdField = value;
            
        

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common")]
        public string ReceiptId
        
            get
            
                return this.receiptIdField;
            
            set
            
                this.receiptIdField = value;
            
        
    

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20", IsNullable = false)]
    public partial class ACABulkReqTrnsmtStsRespGrpDtl
    

        private BulkExchangeFile bulkExchangeFileField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common")]
        public BulkExchangeFile BulkExchangeFile
        
            get
            
                return this.bulkExchangeFileField;
            
            set
            
                this.bulkExchangeFileField = value;
            
        
    

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:us:gov:treasury:irs:common")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:us:gov:treasury:irs:common", IsNullable = false)]
    public partial class BulkExchangeFile
    

        private Include includeField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2004/08/xop/include")]
        public Include Include
        
            get
            
                return this.includeField;
            
            set
            
                this.includeField = value;
            
        
    

    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2004/08/xop/include")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2004/08/xop/include", IsNullable = false)]
    public partial class Include
    

        private string hrefField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string href
        
            get
            
                return this.hrefField;
            
            set
            
                this.hrefField = value;
            
        
    

使用您的 Deserialize 方法和这个新类,我能够成功解析您的 XML 文件。

我会使用这个类与您自己的生成代码进行比较,看看主要区别在哪里。除非您有范围替换生成的代码?

我能发现的第一个是 ACABulkRequestTransmitterStatusDetailResponse 部分类上方的属性需要修改为:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest", IsNullable = false)]

希望这对您有所帮助。

【讨论】:

谢谢凯夫。这确实有帮助。【参考方案2】:

我发现了两个问题:

    更改如下: 从 : [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:us:gov:treasury:irs:ext:aca:air:ty20")] 到 : [XmlRoot(Namespace = "urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest")]

    我更新这部分代码

         private byte[] BulkExchangeFileType;
    
         /// <remarks/>
         /// 
         //changed to string from bytes.
         [System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common")]
         public object BulkExchangeFile
         
             get
             
                 return Encoding.UTF8.GetString(this.BulkExchangeFileType);
             
             set
             
                 this.BulkExchangeFileType = Encoding.UTF8.GetBytes(value.ToString());
                 this.RaisePropertyChanged("BulkExchangeFile");
             
         
    

【讨论】:

以上是关于反序列化 XML 并在 XML 文档中出错 (2, 2)的主要内容,如果未能解决你的问题,请参考以下文章

将 Xml 反序列化为对象时出错 - xmlns='' 不是预期的

将 Xml 反序列化为对象时出错 - xmlns='' 不是预期的

使用 DataContractSerializer 反序列化 XML 时出错

将 xml 反序列化为 c# 对象时,XML 文档 (2, 2) 出现错误

反序列化对对象的 xml 响应时,xml 文档中存在错误

将 XML 文件反序列化为 C# 类对象时出错