vb.NET和复杂的XML结构

时间:2017-04-27 15:50:11

标签: xml vb.net visual-studio-2012

我试图将xml文件转换为复杂的对象类,我不确定为什么Visual Studio / Edit / Past Special作为XML类不能正常工作。当我运行此代码时,我得到“附加信息:XML文档中存在错误(24,4)错误。”

Dim serializer As New XmlSerializer(GetType(rates))
Dim reader As New StreamReader("d:\1Q2017.xml")
Dim rts As New rates
rts = serializer.Deserialize(reader)
reader.Close()

我的班级:

Public Class rates

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
 System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)>
Partial Public Class FILE

    Private tITLEField As String

    Private qUARTERField As String

    Private lINKField As String

    Private eXCHANGE_RATEField As String

    Private rECORDField() As FILERECORD

    Private fOOTNOTESField() As FILEFOOTNOTE

    '''<remarks/>
    Public Property TITLE() As String
        Get
            Return Me.tITLEField
        End Get
        Set
            Me.tITLEField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property QUARTER() As String
        Get
            Return Me.qUARTERField
        End Get
        Set
            Me.qUARTERField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property LINK() As String
        Get
            Return Me.lINKField
        End Get
        Set
            Me.lINKField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property EXCHANGE_RATE() As String
        Get
            Return Me.eXCHANGE_RATEField
        End Get
        Set
            Me.eXCHANGE_RATEField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("RECORD")>
    Public Property RECORD() As FILERECORD()
        Get
            Return Me.rECORDField
        End Get
        Set
            Me.rECORDField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlArrayItemAttribute("FOOTNOTE", IsNullable:=False)>
    Public Property FOOTNOTES() As FILEFOOTNOTE()
        Get
            Return Me.fOOTNOTESField
        End Get
        Set
            Me.fOOTNOTESField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class FILERECORD

    Private itemsField() As Object

    Private itemsElementNameField() As ItemsChoiceType

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("COUNTRY", GetType(String)),
     System.Xml.Serialization.XmlElementAttribute("FUEL_TYPE", GetType(String)),
     System.Xml.Serialization.XmlElementAttribute("JURISDICTION", GetType(FILERECORDJURISDICTION)),
     System.Xml.Serialization.XmlElementAttribute("RATE", GetType(FILERECORDRATE)),
     System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")>
    Public Property Items() As Object()
        Get
            Return Me.itemsField
        End Get
        Set
            Me.itemsField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("ItemsElementName"),
     System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property ItemsElementName() As ItemsChoiceType()
        Get
            Return Me.itemsElementNameField
        End Get
        Set
            Me.itemsElementNameField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class FILERECORDJURISDICTION

    Private idField As String

    Private sURCHARGEField As String

    Private valueField As String

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property ID() As String
        Get
            Return Me.idField
        End Get
        Set
            Me.idField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property SURCHARGE() As String
        Get
            Return Me.sURCHARGEField
        End Get
        Set
            Me.sURCHARGEField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlTextAttribute()>
    Public Property Value() As String
        Get
            Return Me.valueField
        End Get
        Set
            Me.valueField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class FILERECORDRATE

    Private cOUNTRYField As String

    Private rATECHANGEField As Byte

    Private valueField As Decimal

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property COUNTRY() As String
        Get
            Return Me.cOUNTRYField
        End Get
        Set
            Me.cOUNTRYField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property RATECHANGE() As Byte
        Get
            Return Me.rATECHANGEField
        End Get
        Set
            Me.rATECHANGEField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlTextAttribute()>
    Public Property Value() As Decimal
        Get
            Return Me.valueField
        End Get
        Set
            Me.valueField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema:=False)>
Public Enum ItemsChoiceType

    '''<remarks/>
    COUNTRY

    '''<remarks/>
    FUEL_TYPE

    '''<remarks/>
    JURISDICTION

    '''<remarks/>
    RATE
End Enum

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class FILEFOOTNOTE

    Private idField As String

    Private jURISDICTIONField As String

    Private valueField As String

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property ID() As String
        Get
            Return Me.idField
        End Get
        Set
            Me.idField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property JURISDICTION() As String
        Get
            Return Me.jURISDICTIONField
        End Get
        Set
            Me.jURISDICTIONField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlTextAttribute()>
    Public Property Value() As String
        Get
            Return Me.valueField
        End Get
        Set
            Me.valueField = Value
        End Set
    End Property
End Class

End Class

这是XML文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE FILE [
<!ELEMENT FILE (TITLE, QUARTER, LINK, EXCHANGE_RATE, RECORD+, FOOTNOTES+)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT QUARTER (#PCDATA)>
<!ELEMENT LINK (#PCDATA)>
<!ELEMENT EXCHANGE_RATE (#PCDATA)>

<!ELEMENT RECORD (JURISDICTION, COUNTRY, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+, FUEL_TYPE, RATE+)>
<!ELEMENT JURISDICTION (#PCDATA)>
<!ATTLIST JURISDICTION ID CDATA #IMPLIED> 
<!ATTLIST JURISDICTION EFFECTIVE_DATE CDATA #IMPLIED> 
<!ATTLIST JURISDICTION SURCHARGE CDATA #IMPLIED> 
<!ELEMENT COUNTRY (#PCDATA)>
<!ELEMENT FUEL_TYPE (#PCDATA)>  
<!ELEMENT RATE (#PCDATA)>
<!ATTLIST RATE COUNTRY (US|CAN) #REQUIRED>  
<!ATTLIST RATE RATECHANGE (1|0) #REQUIRED>  

<!ELEMENT FOOTNOTES (FOOTNOTE+)>
<!ELEMENT FOOTNOTE (#PCDATA)> 
<!ATTLIST FOOTNOTE ID CDATA #IMPLIED>  
<!ATTLIST FOOTNOTE JURISDICTION CDATA #IMPLIED>  
]>
<FILE>
  <TITLE> Final Fuel Tax Rates </TITLE>
  <QUARTER>1Q2017</QUARTER>
  <LINK>http://www.iftach.org/TaxMatrix/charts/1Q2017.xml</LINK>
  <EXCHANGE_RATE>U.S./Canada Exchange Rate 1.3395 - 0.7465</EXCHANGE_RATE>
  <RECORD>
    <JURISDICTION ID="#15"  >AB</JURISDICTION>
    <COUNTRY>CAN</COUNTRY>
    <FUEL_TYPE>Gasoline</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.4942</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1749</RATE>
      <FUEL_TYPE>Special Diesel</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.5185</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1835</RATE>
      <FUEL_TYPE>Gasohol</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="0">0.3674</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="0">0.1300</RATE>
      <FUEL_TYPE>Propane</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.3527</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1248</RATE>
      <FUEL_TYPE>LNG</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.1068</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.0378</RATE>
      <FUEL_TYPE>CNG</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">1.0681</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.3780</RATE>
      <FUEL_TYPE>Ethanol</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="0">0.3674</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="0">0.1300</RATE>
      <FUEL_TYPE>Methanol</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.4290</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1518</RATE>
      <FUEL_TYPE>E-85</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.3863</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1367</RATE>
      <FUEL_TYPE>M-85</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.4388</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1553</RATE>
      <FUEL_TYPE>A55</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="1">0.4244</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="1">0.1502</RATE>
      <FUEL_TYPE>Biodiesel</FUEL_TYPE>
      <RATE COUNTRY="US" RATECHANGE="0">0.3674</RATE>
      <RATE COUNTRY="CAN" RATECHANGE="0">0.1300</RATE>
  </RECORD>
</FILE>

如果已经涵盖了这一点,我深表歉意,但我搜索的是高低,并且无法找到如何处理这些的示例,在尝试在线格式化程序时XML格式正确。

2 个答案:

答案 0 :(得分:1)

您收到的XML无效。

FILE元素声明如下:

<!ELEMENT FILE (TITLE, QUARTER, LINK, EXCHANGE_RATE, RECORD+, FOOTNOTES+)>

但实际XML中的FILE标记没有FOOTNOTES子元素。

答案 1 :(得分:0)

你的课看起来很好。而不是将它们嵌套在新类rates中,而只是反序列化为FILE类。

Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(FILE))
Dim f As FILE
Using reader As New System.IO.StreamReader("XMLFile1.xml")
    f = serializer.Deserialize(reader)
End Using

修改

在我的测试环境中

  • 使用.NET框架2,3,3.5,4,4.5和4.6.2进行测试。它的工作原理
  • 添加了完全限定的类名(某些.NET类名之前的名称空间,因此您无需导入它们)。
  • 为了测试,我在项目中添加了一个新的xml文件,然后将整个XML复制到文件中,并右键单击文件&gt;&gt;属性&gt;&gt;设置Copy to Output Directory = Copy Always。我这样做是因为我没有"d:\1Q2017.xml"
  • 我还确保FILE类标记为Public。如果它在Module1中定义,则声明Public Module Module1,或移出Module1并将其设为Public

enter image description here