简体   繁体   English

C#将XML反序列化为对象

[英]C# Deserialize XML to object

Having problems deserializing some xml into an object in C#. 将一些xml反序列化为C#中的对象时遇到问题。

The error that I receive is... 我收到的错误是......

xmlns=''> was not expected.

The XSD that I received to generate my class is as follows... 我收到的用于生成课程的XSD如下......

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="xml.AAAAAAA.com/commerce/apres-vente_technique/assistance" xmlns:pgp="xml.AAAAAAA.com/commerce/apres-vente_technique/assistance" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="ListeAvisRemboursements">
        <xs:annotation>
            <xs:documentation>Liste des avis de remboursements</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element name="AvisRemboursement" type="pgp:AvisRemboursementType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="AvisRemboursementType">
        <xs:annotation>
            <xs:documentation>Avis de remboursement lié à une DC</xs:documentation>
        </xs:annotation>
        <xs:sequence>

(snipped) (剪断)

The file that I am attempting to import is as follows: 我尝试导入的文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<ListeAvisRemboursements xmlns:ast="xml.AAAAAAA.com/commerce/apres-vente_technique/assistance">
    <ast:AvisRemboursement NumeroDT="3826961" CodeRA="020545G01" NumeroDC="1">
        <ast:DateTraitement>2010-06-22</ast:DateTraitement>
        <ast:MontantDC>25.0</ast:MontantDC>
        <ast:MontantMO>0.0</ast:MontantMO>
        <ast:SommeAD>25.0</ast:SommeAD>
        <ast:MontantPR>0.0</ast:MontantPR>
        <ast:SommePR>0.0</ast:SommePR>
        <ast:FraisGestion>0.0</ast:FraisGestion>
        <ast:NombreHeuresTotalRemboursees>0</ast:NombreHeuresTotalRemboursees>
        <ast:Etat>C</ast:Etat>
        <ast:NoteCredit>319984</ast:NoteCredit>
        <ast:Imputation>030</ast:Imputation>
        <ast:ListInterventionsPR/>
        <ast:ListInterventionsMO/>
    </ast:AvisRemboursement>

(snipped) (剪断)

I think what is happening is that when .Net attempts to derserialize the xml, it hits the first line which contains the "xmlns:ast" and complaints about it. 认为正在发生的事情是,当.Net试图对xml进行去磁化时,它会触及包含“xmlns:ast”的第一行以及对它的抱怨。 As I understand it, .Net will try to map attributes to a public property in the target class (and it wont find one called xmlns. Or there is something wrong with how I am handling the name spaces. 据我所知,.Net将尝试将属性映射到目标类中的公共属性(并且它不会找到一个名为xmlns。或者我如何处理名称空间有问题。

My deserialization code looks as follows: 我的反序列化代码如下所示:

    XmlDocument _Doc = new XmlDocument();
    _Doc.Load(@"C:\inputfile.xml");

    XmlSerializer _XMLSer = new XmlSerializer(typeof(ListeAvisRemboursements));
    ListeAvisRemboursements _X = (ListeAvisRemboursements)_XMLSer.Deserialize(new StringReader(_Doc.OuterXml));

I have also tried various combinations of adding a namespace manager to the XML document.. 我还尝试了将命名空间管理器添加到XML文档的各种组合。

XmlNamespaceManager _Ns = new XmlNamespaceManager(_Doc.NameTable);
_Ns.AddNamespace("ast", "xml.AAAAAAA.com/commerce/apres-vente_technique/assistance");

I understand there is a way I can use this to tell .Net what namespaces to accept. 我知道有一种方法可以用它来告诉.Net接受哪些命名空间。

Would be greatful for some help iwth this problem. 对于这个问题的一些帮助会很高兴。

--- Updated at request with class snippet (sorry should have included before) this was created with xsd.exe --- ---根据请求更新了类片段(抱歉应该包括之前)这是用xsd.exe创建的---

 /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "xml.AAAAAAA.com/commerce/apres-vente_technique/assistance")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "xml.AAAAAAA.com/commerce/apres-vente_technique/assistance", IsNullable = false)]
    public partial class ListeAvisRemboursements
    {

        private AvisRemboursementType[] avisRemboursementField;

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

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "xml.AAAAAAA.com/commerce/apres-vente_technique/assistance")]
    public partial class AvisRemboursementType
    {

        private System.DateTime dateTraitementField;

        private double montantDCField;

        private double montantMOField;

        private double sommeADField;

        private double montantPRField;

Without a full xsd / xml, or (alternatively) your C# classes, we can't reproduce. 没有完整的xsd / xml,或(或者)你的C#类,我们无法重现。 But working from the xml upwards, this works fine for me; 但是从xml向上工作,这对我来说很好; meaning: the error is not (as far as I can see) in the code/data you posted. 意思是:在您发布的代码/数据中,错误不是(据我所知)。 Can you post a more complete (reproducible) example? 你能发布一个更完整(可重复)的例子吗?

public class ListeAvisRemboursements
{
    private readonly List<AvisRemboursement> items = new List<AvisRemboursement>();
    [XmlElement("AvisRemboursement", Namespace = "xml.AAAAAAA.com/commerce/apres-vente_technique/assistance")]
    public List<AvisRemboursement> Items { get { return items; } }
}
public class AvisRemboursement
{
    [XmlAttribute] public string NumeroDT {get;set;}
    [XmlAttribute] public string CodeRA {get;set;}
    [XmlAttribute] public string NumeroDC {get;set;}
    public DateTime DateTraitement { get; set; }
    public decimal MontantDC { get; set; }
    public decimal MontantMO { get; set; }
    public decimal SommeAD { get; set; }
    public decimal MontantPR { get; set; }
    public decimal SommePR { get; set; }
    public decimal FraisGestion { get; set; }
    public int NombreHeuresTotalRemboursees { get; set; }
    public string Etat { get; set; }
    public string NoteCredit { get; set; }
    public string Imputation { get; set; }
}
static void Main()
{
    var ser = new XmlSerializer(typeof(ListeAvisRemboursements));
    var wrapper = (ListeAvisRemboursements)ser.Deserialize(new StringReader(xml));
    // inspect wrapper.Items etc
}

also works fine with: 也适用于:

var ser = new XmlSerializer(typeof(ListeAvisRemboursements));
using (var reader = XmlReader.Create("inputfile.xml"))
{
    var wrapper = (ListeAvisRemboursements)ser.Deserialize(reader);
}

and: 和:

XmlDocument _Doc = new XmlDocument();
_Doc.Load("inputfile.xml");
var ser = new XmlSerializer(typeof(ListeAvisRemboursements));
var wrapper = (ListeAvisRemboursements)ser.Deserialize(new StringReader(_Doc.OuterXml));

and

XmlDocument _Doc = new XmlDocument();
_Doc.Load("inputfile.xml");
var ser = new XmlSerializer(typeof(ListeAvisRemboursements));
var wrapper = (ListeAvisRemboursements)ser.Deserialize(new XmlNodeReader(_Doc.DocumentElement));

Here's what I am using (sorry am kind of late to the party): 这是我正在使用的(抱歉,我很晚才参加派对):

  Public Function Serialize(Of YourXMLClass)(ByVal obj As YourXMLClass,
                                                      Optional ByVal omitXMLDeclaration As Boolean = True,
                                                      Optional ByVal omitXMLNamespace As Boolean = True) As String

        Dim serializer As New XmlSerializer(obj.GetType)
        Using memStream As New MemoryStream()
            Dim settings As New XmlWriterSettings() With {
                    .Encoding = Encoding.UTF8,
                    .Indent = True,
                    .OmitXmlDeclaration = omitXMLDeclaration}

            Using writer As XmlWriter = XmlWriter.Create(memStream, settings)
                Dim xns As New XmlSerializerNamespaces
                If (omitXMLNamespace) Then xns.Add("", "")
                serializer.Serialize(writer, obj, xns)
            End Using

            Return Encoding.UTF8.GetString(memStream.ToArray())
        End Using
    End Function

 Public Function Deserialize(Of YourXMLClass)(ByVal obj As YourXMLClass, ByVal xml As String) As YourXMLClass
        Dim result As YourXMLClass
        Dim serializer As New XmlSerializer(GetType(YourXMLClass))

        Using memStream As New MemoryStream()
            Dim bytes As Byte() = Encoding.UTF8.GetBytes(xml.ToArray)
            memStream.Write(bytes, 0, bytes.Count)
            memStream.Seek(0, SeekOrigin.Begin)

            Using reader As XmlReader = XmlReader.Create(memStream)
                result = DirectCast(serializer.Deserialize(reader), YourXMLClass)
            End Using

        End Using
        Return result
    End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM