Trouble deserializing a document containing xsi:type attributes

百般思念 提交于 2019-12-11 19:14:52

问题


When parsing XML file I have error in serializer.Deserialize(reader) : Namespace prefix \"java\" not defined

my XML http://www.virtualdtm.ru/files/serverReplays/rFactorHotlapsData.xml

my code

var serializer = new XmlSerializer(typeof(rootDB));
var reader = new XmlTextReader(Server.MapPath(Url.Content("~/Content/xml/rFactorHotlapsData.xml")));
var rFactorHotLapsData = (rootDB)serializer.Deserialize(reader);

my class

//------------------------------------------------------------------------------
// <auto-generated>
//     Этот код создан программой.
//     Исполняемая версия:4.0.30319.17929
//
//     Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
//     повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;
namespace net.vmso.cpanel.Models.rFactorHotLaps
{
}

// 
// Этот исходный код был создан с помощью xsd, версия=4.0.30319.17929.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class rootDB {

    private rootDBListOfCategory[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfCategory", Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public rootDBListOfCategory[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategory {

    private string categoryNameField;

    private rootDBListOfCategoryListOfTrack[] listOfTrackField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string categoryName {
        get {
            return this.categoryNameField;
        }
        set {
            this.categoryNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfTrack", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrack[] listOfTrack {
        get {
            return this.listOfTrackField;
        }
        set {
            this.listOfTrackField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategoryListOfTrack {

    private string trackNameField;

    private rootDBListOfCategoryListOfTrackSlowestLapRecord[] slowestLapRecordField;

    private rootDBListOfCategoryListOfTrackListOfLapRecord[] listOfLapRecordField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string trackName {
        get {
            return this.trackNameField;
        }
        set {
            this.trackNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("slowestLapRecord", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrackSlowestLapRecord[] slowestLapRecord {
        get {
            return this.slowestLapRecordField;
        }
        set {
            this.slowestLapRecordField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfLapRecord", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrackListOfLapRecord[] listOfLapRecord {
        get {
            return this.listOfLapRecordField;
        }
        set {
            this.listOfLapRecordField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategoryListOfTrackSlowestLapRecord {

    private string driverNameField;

    private string sessionNameField;

    private string dateField;

    private string vehicleModNameField;

    private string vehicleNameField;

    private string vehicleCategoryField;

    private string lapTimeField;

    private string lastLapTimeField;

    private string rankField;

    private string sessionIdField;

    private string lapCountField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string driverName {
        get {
            return this.driverNameField;
        }
        set {
            this.driverNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string sessionName {
        get {
            return this.sessionNameField;
        }
        set {
            this.sessionNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string date {
        get {
            return this.dateField;
        }
        set {
            this.dateField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleModName {
        get {
            return this.vehicleModNameField;
        }
        set {
            this.vehicleModNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleName {
        get {
            return this.vehicleNameField;
        }
        set {
            this.vehicleNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleCategory {
        get {
            return this.vehicleCategoryField;
        }
        set {
            this.vehicleCategoryField = value;
        }
    }

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

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

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

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

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

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
    public partial class rootDBListOfCategoryListOfTrackListOfLapRecord {

        private string driverNameField;

        private string sessionNameField;

        private string dateField;

        private string vehicleModNameField;

        private string vehicleNameField;

        private string vehicleCategoryField;

        private string lapTimeField;

        private string lastLapTimeField;

        private string rankField;

        private string sessionIdField;

        private string lapCountField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string driverName {
            get {
                return this.driverNameField;
            }
            set {
                this.driverNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string sessionName {
            get {
                return this.sessionNameField;
            }
            set {
                this.sessionNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string date {
            get {
                return this.dateField;
            }
            set {
                this.dateField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleModName {
            get {
                return this.vehicleModNameField;
            }
            set {
                this.vehicleModNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleName {
            get {
                return this.vehicleNameField;
            }
            set {
                this.vehicleNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleCategory {
            get {
                return this.vehicleCategoryField;
            }
            set {
                this.vehicleCategoryField = value;
            }
        }

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

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

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

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

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

[1]:


回答1:


The java namespace prefix is not defined, but it is used in the xsi:type attributes of your .xml document. If you add an attribute that defines it it to the root of your document, the error will go away.

<rootDB xmlns:java="http://tempuri3.org">

As we later found out, on top of this the xsi:type is messing up the generation of the classes. Badly.

Using XmlSerializer

<listOfTrack xsi:type="java:com.prorfactor.top100.database.Track">

The name of the element is listOfTrack, in the default namespace. Its type however is com.prorfactor.top100.database.Track in the namespace the java prefix is referring to. This happens because the xsi:type attribute changes it. xsd.exe can deal with this, but it needs a little help.

The way I got it to work is to create two .xsds. One for the java namespace and the other for the namespace of the document. They import each other. As an example I'll show the bit that describes the start of the document where the names and types hop around a lot.

<rootDB xmlns="http://tempuri2.org"
        xmlns:java="http://tempuri3.org">
  <listOfCategory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="java:com.prorfactor.top100.database.Category">
    <listOfTrack xsi:type="java:com.prorfactor.top100.database.Track">

For the default namespace, which I called http://tempuri2.org, the schema has to list the names of the elements, because they are in the default namespace:

  <xs:element name="rootDB" >
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="listOfCategory" />
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name="listOfCategory"
              type="java:com.prorfactor.top100.database.Category">
  </xs:element>

  <xs:element name="listOfTrack"
              type="java:com.prorfactor.top100.database.Track">
  </xs:element>

The schema for the java namespace, which I called http://tempuri3.org lists the complextypes that are assigned to the elements using xsi:type:

  <xs:complexType name="com.prorfactor.top100.database.Category"
        xmlns:orig="http://tempuri2.org">
    <xs:sequence>
      <xs:element ref="orig:listOfTrack" minOccurs="0" maxOccurs="unbounded" />
      <xs:element ref="orig:categoryName"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="com.prorfactor.top100.database.Track"
        xmlns:orig="http://tempuri2.org">
    <xs:sequence>
      <xs:element ref="orig:slowestLapRecord" />
      <xs:element ref="orig:listOfLapRecord" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element ref="orig:trackName"/>
    </xs:sequence>
  </xs:complexType>

These two .xsds I compiled and the generated classes manage to deserialize the .xml file.

IF I manually add the java namespace, plus specify the default namespace to the .xml file

So, to be honest, I think you're better off using LINQ to XML:

Using LINQ to XML

XDocument xElement = XDocument.Load(Server.MapPath(Url.Content("~/Content/xml/rFactorHotlapsData.xml")));

// just some selects to show how you select them
var cats = from cat in xElement.Descendants("listOfCategory")
           select new
           {
              Name = cat.Descendants("categoryName").FirstOrDefault().Value,
              Track = from track in cat.Descendants("listOfTrack")
                      select new 
                      {
                         Name = track.Descendants("trackName").FirstOrDefault().Value,
                         LapRecord = from record in cat.Descendants("listOfLapRecord")
                                     select new
                                     {
                                        driverName = record.Descendants("driverName").FirstOrDefault().Value,
                                        sessionName = record.Descendants("sessionName").FirstOrDefault().Value,
                                        date = record.Descendants("date").FirstOrDefault().Value
                                     }
                       }
           };

// And a demo of how to iterate over the result of the select
foreach (var category in cats)
{
   Console.WriteLine(category.Name);
   foreach (var track in category.Track)
   {
      Console.WriteLine("  " + track.Name);
      foreach (var lapRecord in track.LapRecord)
      {
         Console.WriteLine("      " + lapRecord.driverName);
         Console.WriteLine("      " + lapRecord.sessionName);
         Console.WriteLine("      " + lapRecord.date);
      }
   }
}


来源:https://stackoverflow.com/questions/14426276/trouble-deserializing-a-document-containing-xsitype-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!