无法反序列化XML文件

时间:2019-05-06 19:54:24

标签: .net xml vb.net deserialization

我正在尝试将XML文件反序列化为.net对象。我担心文件的格式可能不正确(但是值得怀疑)。该文件可以包含多个带有子组集合的组。我以为我建立了与XML文件相匹配的类。下面是类和反序列化XML的代码。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim export As XMLExport

    Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(XMLExport))
    Dim fn As New FileStream("C:\temp\TEST_AP_20190426_040000.xml", FileMode.Open)
    export = serializer.Deserialize(fn)
    fn.Close()
End Sub

<XmlRoot("XMLExport")>
Public Class XMLExport
    <XmlElement("VoucherHeader")>
    Public Vouchers() As VoucherHeader
End Class

Public Class VoucherHeader
    <XmlElement("VoucherKey")> Public VoucherKey As String
    <XmlElement("VouchNo")> Public VoucherNo As String
    <XmlElement("VoucherTranNo")> Public VoucherTranNo As String
    <XmlElement("VoucherTranDate")> Public VoucherTranDate As Date
    <XmlElement("VoucherHdrCmnt")> Public VoucherHdrCmnt As String
    <XmlElement("VoucherTranAmt")> Public VoucherTranAmt As Double

    <XmlElement("VoucherDetail")>
    Public VoucherDetails() As VoucherDetail
End Class

Public Class VoucherDetail
    <XmlElement("VoucherLineGLAcctNo")> Public VoucherLineGLAcctNo As String
    <XmlElement("VoucherLineAmt")> Public VoucherLineAmt As String
    <XmlElement("ApplyFromTranID")> Public ApplyFromTranID As String
    <XmlElement("ApplyFromTranDate")> Public ApplyFromTranDate As String
    <XmlElement("CheckMemos")> Public CheckMemos As String
    <XmlElement("PmtAmt")> Public PmtAmount As String
    <XmlElement("VoucherLineKey")> Public VoucherLineKey As String
    <XmlElement("VoucherLineDistKey")> Public VoucherLineDistKey As String
    <XmlElement("ApplyToVoucherKey")> Public ApplyToVoucherKey As String
    <XmlElement("EntryNo")> Public EntryNo As String
End Class

我可以收到的XML示例如下:

<?xml version="1.0"?>
<XMLExport>
    <VoucherHeader>
    <VoucherKey>1242550</VoucherKey>
    <VouchNo>0000000976</VouchNo>
    <VoucherTranNo>15W030B041619</VoucherTranNo>
    <VoucherTranDate>2019-04-16T00:00:00</VoucherTranDate>
    <VoucherHdrCmnt>Acct 26-05-39-6922 1</VoucherHdrCmnt>
    <VoucherTranAmt>44.090</VoucherTranAmt>
    <VoucherDetail>
        <VoucherLineGLAcctNo>72100</VoucherLineGLAcctNo>
        <VoucherLineAmt>44.090</VoucherLineAmt>
        <ApplyFromTranID>0000001906-CK</ApplyFromTranID>
        <ApplyFromTranDate>2019-04-25T00:00:00</ApplyFromTranDate>
        <CheckMemos>Acct 26-05-39-6922 1</CheckMemos>
        <PmtAmt>444.090</PmtAmt>
        <VoucherLineKey>1734668</VoucherLineKey>
        <VoucherLineDistKey>1734670</VoucherLineDistKey>
        <ApplyToVoucherKey>12344</ApplyToVoucherKey>
        <EntryNo>1</EntryNo>
    </VoucherDetail>
    <VoucherDetail>
        <VoucherLineGLAcctNo>72100</VoucherLineGLAcctNo>
        <VoucherLineAmt>44.090</VoucherLineAmt>
        <ApplyFromTranID>0000001906-CK</ApplyFromTranID>
        <ApplyFromTranDate>2019-04-25T00:00:00</ApplyFromTranDate>
        <CheckMemos>Acct 26-05-39-6922 1</CheckMemos>
        <PmtAmt>46.090</PmtAmt>
        <VoucherLineKey>1734368</VoucherLineKey>
        <VoucherLineDistKey>1734670</VoucherLineDistKey>
        <ApplyToVoucherKey>1242550</ApplyToVoucherKey>
        <EntryNo>1</EntryNo>
    </VoucherDetail>
    <VoucherDetail>
        <VoucherLineGLAcctNo>72100</VoucherLineGLAcctNo>
        <VoucherLineAmt>44.090</VoucherLineAmt>
        <ApplyFromTranID>0000001906-CK</ApplyFromTranID>
        <ApplyFromTranDate>2019-04-25T00:00:00</ApplyFromTranDate>
        <CheckMemos>Acct 43436922 1</CheckMemos>
        <PmtAmt>44.090</PmtAmt>
        <VoucherLineKey>1734668</VoucherLineKey>
        <VoucherLineDistKey>1734670</VoucherLineDistKey>
        <ApplyToVoucherKey>1242550</ApplyToVoucherKey>
        <EntryNo>1</EntryNo>
    </VoucherDetail>
    </VoucherHeader>
    <VoucherHeader>
        <VoucherKey>1242552</VoucherKey>
        <VouchNo>0000000977</VouchNo>
        <VoucherTranNo>14483</VoucherTranNo>
        <VoucherTranDate>2019-04-11T00:00:00</VoucherTranDate>
        <VoucherHdrCmnt>Cust 2449 Spring 2019 Inspection</VoucherHdrCmnt>
        <VoucherTranAmt>975.000</VoucherTranAmt>
        <VoucherDetail>
            <VoucherLineGLAcctNo>70200</VoucherLineGLAcctNo>
            <VoucherLineAmt>975.000</VoucherLineAmt>
            <ApplyFromTranID>0000001905-CK</ApplyFromTranID>
            <ApplyFromTranDate>2019-04-25T00:00:00</ApplyFromTranDate>
            <CheckMemos>Cust 2449</CheckMemos>
            <PmtAmt>975.000</PmtAmt>
            <VoucherLineKey>1734669</VoucherLineKey>
            <VoucherLineDistKey>1734671</VoucherLineDistKey>
            <ApplyToVoucherKey>1242552</ApplyToVoucherKey>
            <EntryNo>1</EntryNo>
        </VoucherDetail>
    </VoucherHeader>
    <VoucherHeader>
        <VoucherKey>1242553</VoucherKey>
        <VouchNo>0000000978</VouchNo>
        <VoucherTranNo>354112</VoucherTranNo>
        <VoucherTranDate>2019-04-15T00:00:00</VoucherTranDate>
        <VoucherHdrCmnt>Cust 3238</VoucherHdrCmnt>
        <VoucherTranAmt>135.000</VoucherTranAmt>
        <VoucherDetail>
            <VoucherLineGLAcctNo>70500</VoucherLineGLAcctNo>
            <VoucherLineAmt>135.000</VoucherLineAmt>
            <ApplyFromTranID>0000001904-CK</ApplyFromTranID>
            <ApplyFromTranDate>2019-04-25T00:00:00</ApplyFromTranDate>
            <CheckMemos>Cust 3238</CheckMemos>
            <PmtAmt>135.000</PmtAmt>
            <VoucherLineKey>1734695</VoucherLineKey>
            <VoucherLineDistKey>1734697</VoucherLineDistKey>
            <ApplyToVoucherKey>1242553</ApplyToVoucherKey>
            <EntryNo>1</EntryNo>
        </VoucherDetail>
    </VoucherHeader>
</XMLExport>

我希望遍历“ Vouchers”的集合,因为可以有多个VoucherHeader,并且在每个VoucherHeader中,都可以遍历VoucherDetails。

我试图更改类,项目等上的XML装饰,但是现在代码将在serializer.Deserialize(fn)行上失败,但有以下例外:

  

XMLReader.exe中发生了类型为'System.InvalidCastException'的未处理的异常
  附加信息:
  无法将类型为“ XMLReader.XMLExport”的对象转换为类型为“ XMLReader.XMLExport []”。

2 个答案:

答案 0 :(得分:0)

无法测试,因为我现在不在家,但看来您正在尝试转换数组。试试这个:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
     Dim export As XMLExport

     Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(XMLExport))
     Dim fn As New FileStream("C:\temp\TEST_AP_20190426_040000.xml", FileMode.Open)
     export = serializer.Deserialize(fn)
     fn.Close()
End Sub

这样,反序列化时就不会使用数组。

答案 1 :(得分:0)

您需要进行以下更改:

(1)根元素未定义为数组的容器。将声明更改为对XMLExport的单个引用。

Dim export As XMLExport

(2) XmlRoot在您应用的位置将被忽略。它将起作用的唯一位置是在XMLExport类上,因为这是文档的根目录。名称与类匹配,因此没有区别。仅当您希望在不更改元素名称的情况下灵活地使用类名时,这才重要。

(3)使用XmlArray代替XmlArrayItemXmlElement。串行器已经知道它是一个数组。仅使用XmlElement,它将使用该元素名称作为元素的内联列表,而不是单个父元素中的元素。

<XmlRoot("XMLExport")>
Public Class XMLExport
    <XmlElement("VoucherHeader")>
    Public Vouchers() As VoucherHeader
End Class

(4)。有关优惠券详细信息,同样。

Public Class VoucherHeader
    '...

    <XmlElement("VoucherDetail")>
    Public VoucherDetails() As VoucherDetail
End Class

(5)VoucherHeader中,您具有类型Double的三个属性,但是内容是文本或日期/时间。像这样更改类型:

<XmlElement("VoucherTranNo")> Public VoucherTranNo As String
<XmlElement("VoucherTranDate")> Public VoucherTranDate As Date
<XmlElement("VoucherHdrCmnt")> Public VoucherHdrCmnt As String