反序列化自定义 XML 时出现 InvalidOperationException(缺少命名空间)

InvalidOperationException when deserializing custom XML (lack of namespace)

我有一个 XML 文档以以下根开头:

<?xml version="1.0" encoding="UTF-8"?>
<JPK
    xmlns="http://jpk.mf.gov.pl/wzor/2019/09/27/09271/"
    xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/08/24/eD/DefinicjeTypy/">
    <Naglowek>
        <KodFormularza kodSystemowy="SomeCode" wersjaSchemy="1-0">SomeCode</KodFormularza>
        <WariantFormularza>3</WariantFormularza>
        <CelZlozenia>1</CelZlozenia>
        <DataWytworzeniaJPK>2021-06-30T15:57:53</DataWytworzeniaJPK>
        <DataOd>2021-05-01</DataOd>
        <DataDo>2021-05-31</DataDo>
        <KodUrzedu>0000</KodUrzedu>
    </Naglowek>
    <Podmiot1>
        <IdentyfikatorPodmiotu>
            <etd:NIP>111111</etd:NIP>
            <etd:PelnaNazwa>SomeName</etd:PelnaNazwa>
        </IdentyfikatorPodmiotu>
        <AdresPodmiotu>
            <etd:Wojewodztwo>voivodeship</etd:Wojewodztwo>
            <etd:KodKraju>PL</etd:KodKraju>
            <etd:Powiat>Danzig</etd:Powiat>
            <etd:Gmina>Danzig</etd:Gmina>
            <etd:Ulica>SomeStreet</etd:Ulica>
            <etd:NrDomu>81</etd:NrDomu>
            <etd:NrLokalu>1</etd:NrLokalu>
            <etd:Miejscowosc>Danzig</etd:Miejscowosc>
            <etd:KodPocztowy>10-101</etd:KodPocztowy>
        </AdresPodmiotu>
    </Podmiot1>
    <!-- These can be many in the same element, there's no root for this list -->
    <Faktura>
        <KodWaluty>PLN</KodWaluty>
        <P_1>2021-05-04</P_1>
        <P_2A>11 / 1111</P_2A>
        <P_3A>Some Company</P_3A>
        <P_3B>Some Address</P_3B>
        <P_3C>Some Name</P_3C>
        <P_3D>Some Other Address</P_3D>
        <P_4B>Phone1</P_4B>
        <P_5B>Phone2</P_5B>
        <P_13_1>1.00</P_13_1>
        <P_14_1>1.25</P_14_1>
        <P_15>SomeDecimalNumber</P_15>
        <P_16>false</P_16>
        <P_17>false</P_17>
        <P_18>false</P_18>
        <P_18A>false</P_18A>
        <P_19>false</P_19>
        <P_20>false</P_20>
        <P_21>false</P_21>
        <P_22>false</P_22>
        <P_23>false</P_23>
        <P_106E_2>false</P_106E_2>
        <P_106E_3>false</P_106E_3>
        <RodzajFaktury>InvoiceType</RodzajFaktury>
    </Faktura>
    <!-- These can be many in the same element, there's no root for this list -->
    <FakturaCtrl>
        <LiczbaFaktur>1</LiczbaFaktur>
        <WartoscFaktur>2.00</WartoscFaktur>
    </FakturaCtrl>
    <!-- These can be many in the same element, there's no root for this list -->
    <FakturaWiersz>
        <P_2B>04/123</P_2B>
        <P_7>Text</P_7>
        <P_8B>1.000000</P_8B>
        <P_9A>7.00</P_9A>
        <P_11>7.00</P_11>
        <P_12>11</P_12>
    </FakturaWiersz>
    <FakturaWierszCtrl>
        <LiczbaWierszyFaktur>11</LiczbaWierszyFaktur>
        <WartoscWierszyFaktur>11.2</WartoscWierszyFaktur>
    </FakturaWierszCtrl>
</JPK>

它有大写字母。我对它的定义没有影响,需要自己调整。

我已经为它写了一个class:

    [XmlRoot(ElementName = "JPK", Namespace = "http://jpk.mf.gov.pl/wzor/2019/09/27/09271/", IsNullable = false)]
    public class Jpk
    {
        public Jpk() { }

        [XmlElement(ElementName = "Naglowek")]
        public JpkHeader Header { get; set; }

        [XmlElement(ElementName = "Podmiot1")]
        public JpkSubject Subject { get; set; }

        [XmlElement(ElementName = "Faktura")]
        public JpkInvoice[] Invoices { get; set; }

        [XmlElement(ElementName = "FakturaCtrl")]
        public JpkInvoiceControl[] InvoiceControls { get; set; }

        [XmlElement(ElementName = "FakturaWiersz")]
        public JpkInvoiceRow[] InvoiceRows { get; set; }

        [XmlElement(ElementName = "FakturaWierszCtrl")]
        public JpkInvoiceRowControl InvoiceRowControl { get; set; }
    }

    public class JpkHeader
    {
        [XmlElement(ElementName = "KodFormularza")]
        public string FormCode { get; set; }

        [XmlElement(ElementName = "WariantFormularza")]
        public string Variant { get; set; }

        [XmlElement(ElementName = "CelZlozenia")]
        public int Purpose { get; set; }

        [XmlElement(ElementName = "DataWytworzeniaJPK")]
        public DateTime CreationDate { get; set; }

        [XmlElement(ElementName = "DataOd")]
        public DateTime DateFrom { get; set; }

        [XmlElement(ElementName = "DataDo")]
        public DateTime DateTo { get; set; }

        [XmlElement(ElementName = "KodUrzedu")]
        public string OfficeCode { get; set; }
    }

    public class JpkInvoice
    {
        [XmlElement(ElementName = "KodWaluty")]
        public string CurrencyCode { get; set; }

        public DateTime P_1 { get; set; }
        public string P_2A { get; set; }
        public string P_3A { get; set; }
        public string P_3B { get; set; }
        public string P_3C { get; set; }
        public string P_3D { get; set; }
        public string P_4B { get; set; }
        public string P_5B { get; set; }
        public decimal P_13_1 { get; set; }
        public decimal P_14_1 { get; set; }
        public decimal P_15 { get; set; }
        public bool P_16 { get; set; }
        public bool P_17 { get; set; }
        public bool P_18 { get; set; }
        public bool P_18A { get; set; }
        public bool P_19 { get; set; }
        public bool P_20 { get; set; }
        public bool P_21 { get; set; }
        public bool P_22 { get; set; }
        public bool P_23 { get; set; }
        public bool P_106E_2 { get; set; }
        public bool P_106E_3 { get; set; }

        [XmlElement(ElementName = "RodzajFaktury")]
        public string InvoiceType { get; set; }
    }

    public class JpkInvoiceControl
    {
        [XmlElement(ElementName = "LiczbaFaktur")]
        public int InvoiceAmount { get; set; }

        [XmlElement(ElementName = "WartoscFaktur")]
        public decimal InvoiceValue { get; set; }
    }

    public class JpkInvoiceRow
    {
        public string P_2B { get; set; }
        public string P_7 { get; set; }
        public double P_8B { get; set; }
        public decimal P_9A { get; set; }
        public decimal P_11 { get; set; }
        public int P_12 { get; set; }

    }

    public class JpkInvoiceRowControl
    {
        [XmlElement(ElementName = "LiczbaWierszyFaktur")]
        public int InvoiceRowAmount { get; set; }

        [XmlElement(ElementName = "WartoscWierszyFaktur")]
        public decimal InvoiceRowSum { get; set; }
    }

    public class JpkSubject
    {
        [XmlElement(ElementName = "IdentyfikatorPodmiotu")]
        public SubjectID SubjectId { get; set; }

        [XmlElement(ElementName = "AdresPodmiotu")]
        public SubjectAddress Address { get; set; }
    }

    public class SubjectID
    {
        [XmlElement(ElementName = "etd:NIP")]
        public string NIP { get; set; }

        [XmlElement(ElementName = "etd:PelnaNazwa")]
        public string FullName { get; set; }
    }

    public class SubjectAddress
    {
        [XmlElement(ElementName = "etd:KodKraju")]
        public string CountryCode { get; set; }

        [XmlElement(ElementName = "etd:Wojewodztwo")]
        public string Province { get; set; }

        [XmlElement(ElementName = "etd:Powiat")]
        public string District { get; set; }

        [XmlElement(ElementName = "etd:Gmina")]
        public string Community { get; set; }

        [XmlElement(ElementName = "etd:Ulica")]
        public string StreetName { get; set; }

        [XmlElement(ElementName = "etd:NrDomu")]
        public int HouseNumber { get; set; }

        [XmlElement(ElementName = "etd:NrLokalu")]
        public int FlatNumber { get; set; }

        [XmlElement(ElementName = "etd:Miejscowosc")]
        public string City { get; set; }

        [XmlElement(ElementName = "etd:KodPocztowy")]
        public string PostalCode { get; set; }
    }

我有反序列化它的代码:

var serializer = new XmlSerializer(typeof(Etc), new XmlRootAttribute("JPK"));
var streamReader = new StreamReader(@"C:\_NotInGit\sample.xml");
var smth = (Jpk)serializer.Deserialize(streamReader);

当我运行这个代码时,我得到

System.InvalidOperationException: 'There is an error in XML document (2, 2).' InvalidOperationException: was not expected.

at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)
at MyProject.Program.Main(String[] args) in C:\MyProject\Program.cs:line 15

我运行我通过互联网查询:

我的蜘蛛感觉告诉我这可能与第二个定义有关,但我不确定如何处理它。我试图将其删除(出于科学目的),但它并没有改变响应。

还有什么我想念的吗?

剧透警告:它(也)是关于第二个命名空间定义的。值得庆幸的是,接受的答案向我展示了如何声明它,以及如何处理 etd 部分。那,以及从代码中删除 new XmlRootAttribute("JPK")

在尝试调试 XML 反序列化问题时,我发现序列化我使用一些示例数据创建的 class 很有帮助。然后,我检查我序列化的数据(保存到 XML 文件)是否与我尝试反序列化的 XML 文件相同。

在您发布的 XML 数据中,在 Faktura 内,是以下内容:

   <P_15>SomeDecimalNumber</P_15>

然后在class JpkInvoice中是这样的:

   public decimal P_15 { get; set; }

这是一个问题,因为 XML 文件中的值是 string,而 属性 声明为 decimal。 属性 数据类型需要为 string 或 XML 文件中的值需要更改为有效的十进制值。为了测试,在 XML 中,我将 <P_15>SomeDecimalNumber</P_15> 替换为 <P_15>0</P_15>

我已经使用您提供的 XML 测试了以下代码 - 使用上述 XML 数据修改。我更改了 属性 名称以匹配 XML 文件中的内容,因为我发现这样更容易。如果您愿意,可以重命名它们。此外,我更喜欢使用 List 而不是数组,因此您也会在代码中注意到这一点。

在下面的代码中,必须使用以下 using 语句:

using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

创建一个class(名称:Jpk)

Class: Jpk

[XmlRoot(ElementName = "JPK", Namespace = "http://jpk.mf.gov.pl/wzor/2019/09/27/09271/", IsNullable = false)]
public class Jpk
{
    [XmlElement(ElementName = "Naglowek")]
    public JpkNaglowek Naglowek { get; set; } = new JpkNaglowek(); //Header

    [XmlElement(ElementName = "Podmiot1")]
    public JpkPodmiot1 Podmiot1 { get; set; } = new JpkPodmiot1(); //Subject

    [XmlElement(ElementName = "Faktura")]
    public List<JpkFaktura> Faktura { get; set; } = new List<JpkFaktura>(); //Invoices

    [XmlElement(ElementName = "FakturaCtrl")]
    public List<JpkFakturaCtrl> FakturaCtrl { get; set; } = new List<JpkFakturaCtrl>(); //InvoiceControls

    [XmlElement(ElementName = "FakturaWiersz")]
    public List<JpkFakturaWiersz> FakturaWiersz { get; set; } = new List<JpkFakturaWiersz>(); //InvoiceRows

    [XmlElement(ElementName = "FakturaWierszCtrl")]
    public List<JpkFakturaWierszCtrl> FakturaWierszCtrl { get; set; } = new List<JpkFakturaWierszCtrl>(); //InvoiceRowControl

}

Class: JpkFaktura

public class JpkFaktura
{
    private string p_1 = string.Empty;

    [XmlIgnore]
    public DateTime P_1Dt { get; private set; } = DateTime.MinValue; //value of P_1 as DateTime

    [XmlElement]
    public string KodWaluty { get; set; }

    [XmlElement]
    public string P_1 
    {
        get
        {
            return this.p_1;
        }
        set
        {
            this.p_1 = value;
            
            //try to convert to DateTime
            DateTime dt = DateTime.MinValue;
            DateTime.TryParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);

            //set value
            this.P_1Dt = dt;
        }
    }

    [XmlElement]
    public string P_2A { get; set; }

    [XmlElement]
    public string P_3A { get; set; }

    [XmlElement]
    public string P_3B { get; set; }

    [XmlElement]
    public string P_3C { get; set; }

    [XmlElement]
    public string P_3D { get; set; }

    [XmlElement]
    public string P_4B { get; set; }

    [XmlElement]
    public string P_5B { get; set; }

    [XmlElement]
    public decimal P_13_1 { get; set; }

    [XmlElement]
    public decimal P_14_1 { get; set; }

    [XmlElement]
    public decimal P_15 { get; set; }

    [XmlElement]
    public bool P_16 { get; set; } = false;

    [XmlElement]
    public bool P_17 { get; set; } = false;

    [XmlElement]
    public bool P_18 { get; set; } = false;

    [XmlElement]
    public bool P_18A { get; set; } = false;

    [XmlElement]
    public bool P_19 { get; set; } = false;

    [XmlElement]
    public bool P_20 { get; set; } = false;

    [XmlElement]
    public bool P_21 { get; set; } = false;

    [XmlElement]
    public bool P_22 { get; set; } = false;

    [XmlElement]
    public bool P_23 { get; set; } = false;

    [XmlElement]
    public bool P_106E_2 { get; set; } = false;

    [XmlElement]
    public bool P_106E_3 { get; set; } = false;

    [XmlElement]
    public string RodzajFaktury { get; set; }
}

注意:在上面的代码中,您会注意到一个名为 P_1Dt 的 属性。它是一个 public 属性,将 P_1 的值保存为 DateTime。通过指定 [XmlIgnore],此 属性 将在 deserialization/serialization 期间被忽略。在XML中,数据的格式是yyyy-MM-dd(例如:2021-05-01),这就是为什么需要将数据类型指定为字符串的原因。如果数据类型指定为 DateTime,则在序列化 XML 文件中的数据时,该数据将类似于 yyyy-MM-ddTHH:mm:ss(例如:2021-05-01T00:00:00)

Class: JpkFakturaCtrl

public class JpkFakturaCtrl
{
    [XmlElement]
    public decimal LiczbaFaktur { get; set; }

    [XmlElement]
    public decimal WartoscFaktur { get; set; }
}

Class: JpkFakturaWiersz

public class JpkFakturaWiersz
{
    [XmlElement]
    public string P_2B { get; set; }

    [XmlElement]
    public string P_7 { get; set; }

    [XmlElement]
    public decimal P_8B { get; set; }

    [XmlElement]
    public decimal P_9A { get; set; }

    [XmlElement]
    public decimal P_11 { get; set; }

    [XmlElement]
    public int P_12 { get; set; }
}

Class: JpkFakturaWierszCtrl

public class JpkFakturaWierszCtrl
{
    [XmlElement]
    public decimal LiczbaWierszyFaktur { get; set; }

    [XmlElement]
    public decimal WartoscWierszyFaktur { get; set; }
}

Class: JpkNaglowek

public class JpkNaglowek
{
    private string dataOd = string.Empty;
    private string dataDo = string.Empty;

    [XmlIgnore]
    public DateTime DataDoDt { get; private set; } //value of DataDo as DateTime

    [XmlIgnore]
    public DateTime DataOdDt { get; private set; } //value of DataDo as DateTime

    [XmlElement(ElementName = "KodFormularza")]
    public JpkNaglowekKodFormularza KodFormularza { get; set; } = new JpkNaglowekKodFormularza(); //FormCode

    [XmlElement(ElementName = "WariantFormularza")]
    public string WariantFormularza { get; set; } //Variant

    [XmlElement(ElementName = "CelZlozenia")]
    public int CelZlozenia { get; set; } //Purpose

    [XmlElement(ElementName = "DataWytworzeniaJPK")]
    public DateTime DataWytworzeniaJPK { get; set; } //CreationDate - DateTime

    //DateFrom
    [XmlElement(ElementName = "DataOd")]
    public string DataOd 
    {
        get
        {
            return this.dataOd;
        }
        set
        {
            this.dataOd = value;

            //try to convert to DateTime
            DateTime dt = DateTime.MinValue;
            DateTime.TryParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);

            //set value
            this.DataOdDt = dt;
        }
    }

    //DateTo
    [XmlElement(ElementName = "DataDo")]
    public string DataDo
    {
        get
        {
            return this.dataDo;
        }
        set
        {
            this.dataDo = value;

            //try to convert to DateTime
            DateTime dt = DateTime.MinValue;
            DateTime.TryParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);

            //set value
            this.DataDoDt = dt;
        }
    }

    [XmlElement(ElementName = "KodUrzedu")]
    public string KodUrzedu { get; set; }
}

注意:在上面的代码中,您会注意到属性:DataDoDtDataOdDt。它们是 public 属性,分别保存 DataDoDataOd 的值,如 DateTime。通过指定 [XmlIgnore],此 属性 将在 deserialization/serialization 期间被忽略。在XML中,数据的格式是yyyy-MM-dd(例如:2021-05-01),这就是为什么需要将数据类型指定为字符串的原因。如果数据类型指定为 DateTime,则在序列化 XML 文件中的数据时,该数据将类似于 yyyy-MM-ddTHH:mm:ss(例如:2021-05-01T00:00:00)

Class: JpkNaglowekKodFormularza

public class JpkNaglowekKodFormularza
{
    [XmlAttribute(AttributeName = "kodSystemowy")]
    public string kodSystemowy { get; set; }

    [XmlAttribute(AttributeName = "wersjaSchemy")]
    public string wersjaSchemy { get; set; }

    [XmlText]
    public string Value { get; set; }
}

Class: JpkPodmiot1

public class JpkPodmiot1
{
    [XmlElement(ElementName = "IdentyfikatorPodmiotu")]
    public JpkPodmiot1IdentyfikatorPodmiotu IdentyfikatorPodmiotu { get; set; } = new JpkPodmiot1IdentyfikatorPodmiotu(); //SubjectId

    [XmlElement(ElementName = "AdresPodmiotu")]
    public JpkPodmiot1AdresPodmiotu AdresPodmiotu { get; set; } = new JpkPodmiot1AdresPodmiotu(); //Address
}

Class: JpkPodmiot1IdentyfikatorPodmiotu

[System.Xml.Serialization.XmlType(Namespace = "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/08/24/eD/DefinicjeTypy/")]
public class JpkPodmiot1IdentyfikatorPodmiotu
{
    [XmlElement(ElementName = "NIP")]
    public string NIP { get; set; }

    [XmlElement(ElementName = "PelnaNazwa")] 
    public string PelnaNazwa { get; set; } //FullName
}

在上面的代码中,请注意指定了命名空间。

Class: JpkPodmiot1AdresPodmiotu

[System.Xml.Serialization.XmlType(Namespace = "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/08/24/eD/DefinicjeTypy/")]
public class JpkPodmiot1AdresPodmiotu
{
    [XmlElement(ElementName = "Wojewodztwo")]
    public string Wojewodztwo { get; set; } //Province

    [XmlElement(ElementName = "KodKraju")]
    public string KodKraju { get; set; } //CountryCode

    [XmlElement(ElementName = "Powiat")]
    public string Powiat { get; set; } //District

    [XmlElement(ElementName = "Gmina")]
    public string Gmina { get; set; } //Community

    [XmlElement(ElementName = "Ulica")]
    public string Ulica { get; set; } //StreetName

    [XmlElement(ElementName = "NrDomu")] 
    public Int32 NrDomu { get; set; } //HouseNumber

    [XmlElement(ElementName = "NrLokalu")]
    public Int32 NrLokalu { get; set; } //FlatNumber

    [XmlElement(ElementName = "Miejscowosc")]
    public string Miejscowosc { get; set; } //City

    [XmlElement(ElementName = "KodPocztowy")]
    public string KodPocztowy { get; set; } //PostalCode

}

在上面的代码中,请注意指定了命名空间。

这里有一个方法可以用来用一些测试数据填充 Jpk 的实例——它是您在上面指定的 XML 文件中的数据。它对测试 XML 序列化很有用。

CreateTestData

private Jpk CreateTestData()
{
    Jpk jpk = new Jpk();

    //Naglowek
    jpk.Naglowek.KodFormularza.kodSystemowy = "SomeCode";
    jpk.Naglowek.KodFormularza.wersjaSchemy = "1-0";
    jpk.Naglowek.KodFormularza.Value = "SomeCode";
    jpk.Naglowek.WariantFormularza = "3";
    jpk.Naglowek.CelZlozenia = 1;
    jpk.Naglowek.DataWytworzeniaJPK = DateTime.ParseExact("2021-06-30T15:57:53", "yyyy-MM-ddTHH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); //"2021-06-30T15:57:53"; //ToDo: change to DateTime
    jpk.Naglowek.DataOd = "2021-05-01";
    jpk.Naglowek.DataDo = "2021-05-31";
    jpk.Naglowek.KodUrzedu = "0000";

    //Podmiot1
    jpk.Podmiot1.IdentyfikatorPodmiotu.NIP = "111111";
    jpk.Podmiot1.IdentyfikatorPodmiotu.PelnaNazwa = "SomeName";
    jpk.Podmiot1.AdresPodmiotu.Wojewodztwo = "voivodeship";
    jpk.Podmiot1.AdresPodmiotu.KodKraju = "PL";
    jpk.Podmiot1.AdresPodmiotu.Powiat = "Danzig";
    jpk.Podmiot1.AdresPodmiotu.Gmina = "Danzig";
    jpk.Podmiot1.AdresPodmiotu.Ulica = "SomeStreet";
    jpk.Podmiot1.AdresPodmiotu.NrDomu = 81;
    jpk.Podmiot1.AdresPodmiotu.NrLokalu = 1;
    jpk.Podmiot1.AdresPodmiotu.Miejscowosc = "Danzig";
    jpk.Podmiot1.AdresPodmiotu.KodPocztowy = "10-101";

    //Faktura
    JpkFaktura jpkFaktura = new JpkFaktura();
    jpkFaktura.KodWaluty = "PLN";
    jpkFaktura.P_1 = "2021-05-04";
    jpkFaktura.P_2A = "11 / 1111";
    jpkFaktura.P_3A = "Some Company";
    jpkFaktura.P_3B = "Some Address";
    jpkFaktura.P_3C = "Some Name";
    jpkFaktura.P_3D = "Some Other Address";
    jpkFaktura.P_4B = "Phone1";
    jpkFaktura.P_5B = "Phone2";
    jpkFaktura.P_13_1 = 1.00m; //need to use 'm' for decimal number
    jpkFaktura.P_14_1 = 1.25m; //need to use 'm' for decimal number
    jpkFaktura.P_15 = 0m; //need to use 'm' for decimal number
    jpkFaktura.P_16 = false;
    jpkFaktura.P_17 = false;
    jpkFaktura.P_18 = false;
    jpkFaktura.P_18A = false;
    jpkFaktura.P_19 = false;
    jpkFaktura.P_20 = false;
    jpkFaktura.P_21 = false;
    jpkFaktura.P_22 = false;
    jpkFaktura.P_23 = false;
    jpkFaktura.P_106E_2 = false;
    jpkFaktura.P_106E_3 = false;
    jpkFaktura.RodzajFaktury = "InvoiceType";

    //add
    jpk.Faktura.Add(jpkFaktura);

    //FakturaCtrl
    JpkFakturaCtrl jpkFakturaCtrl = new JpkFakturaCtrl();
    jpkFakturaCtrl.LiczbaFaktur = 1m; //need to use 'm' for decimal number
    jpkFakturaCtrl.WartoscFaktur = 2.00m; //need to use 'm' for decimal number

    //add
    jpk.FakturaCtrl.Add(jpkFakturaCtrl);

    //FakturaWiersz
    JpkFakturaWiersz jpkFakturaWiersz = new JpkFakturaWiersz();
    jpkFakturaWiersz.P_2B = "04/123";
    jpkFakturaWiersz.P_7 = "Text";
    jpkFakturaWiersz.P_8B = 1.000000m; //need to use 'm' for decimal number
    jpkFakturaWiersz.P_9A = 7.00m; //need to use 'm' for decimal number
    jpkFakturaWiersz.P_11 = 7.00m; //need to use 'm' for decimal number
    jpkFakturaWiersz.P_12 = 11;

    //add
    jpk.FakturaWiersz.Add(jpkFakturaWiersz);

    //FakturaWierszCtrl
    JpkFakturaWierszCtrl jpkFakturaWierszCtrl = new JpkFakturaWierszCtrl();
    jpkFakturaWierszCtrl.LiczbaWierszyFaktur = 11m; //need to use 'm' for decimal number
    jpkFakturaWierszCtrl.WartoscWierszyFaktur = 11.2m; //need to use 'm' for decimal number

    //add
    jpk.FakturaWierszCtrl.Add(jpkFakturaWierszCtrl);

    return jpk;
}

用法:

Jpk jpk1 = CreateTestData();

对于 XML 序列化,使用以下内容:

public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
    try
    {
        if (string.IsNullOrEmpty(xmlFilename))
        {
            return;
        }//if

        using (System.IO.TextWriter xmlStream = new System.IO.StreamWriter(xmlFilename))
        {
            //specify namespaces
            System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
            ns.Add(string.Empty, "http://jpk.mf.gov.pl/wzor/2019/09/27/09271/");
            ns.Add("etd", "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/08/24/eD/DefinicjeTypy/");

            //create new instance
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());

            //write XML to file
            serializer.Serialize(xmlStream, obj, ns);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
        throw ex;
    }
}

用法:

Jpk jpk1 = CreateTestData();
SerializeObjectToXMLFile(jpk1, @"C:\Temp\Test.xml");

反序列化,使用如下代码:

public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
    T rObject = default(T);

    try
    {

        if (string.IsNullOrEmpty(xmlFilename))
        {
            return default(T);
        }

        using (System.IO.StreamReader xmlStream = new System.IO.StreamReader(xmlFilename))
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            rObject = (T)serializer.Deserialize(xmlStream);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
        throw ex;
    }

    return rObject;
}

用法:

Jpk jpk1 = DeserializeXMLFileToObject<Jpk>(@"C:\Temp\Test.xml");