InvalidOperationException при десериализации пользовательского XML (отсутствие пространства имен)

avatar
Maurice Klimek
1 июля 2021 в 18:41
245
1
0

У меня есть документ 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>

Написано заглавными буквами. На его определение я не влияю, мне нужно настроить самому.

Я написал для него класс:

    [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: "Ошибка в XML-документе (2, 2)". InvalidOperationException: не ожидалось.

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") из кода.

Источник
user9938
2 июля 2021 в 00:37
0

Ваш код слишком минимален, чтобы быть полезным. Пожалуйста, предоставьте полный действительный образец XML-файла, а не только первую строку.

Maurice Klimek
2 июля 2021 в 17:52
0

Добавлен. Надеюсь, это поможет.

Ответы (1)

avatar
user9938
3 июля 2021 в 00:04
1

При попытке отладки проблемы десериализации XML я считаю полезным сериализовать класс, который я создал, используя некоторые образцы данных. Затем я проверяю, совпадают ли данные, которые я сериализовал (сохранил в XML-файл), с XML-файлом, который я пытаюсь десериализовать.

В опубликованных вами XML-данных в пределах Faktura содержится следующее:

   <P_15>SomeDecimalNumber</P_15>

Тогда в классе 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 System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

Создать класс (имя: Jpk)

Класс: 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

}

Класс: 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. Это общедоступное свойство, которое содержит значение P_1 как DateTime. При указании [XmlIgnore] это свойство будет игнорироваться во время десериализации/сериализации. В XML формат данных — yyyy-MM-dd (пример: 2021-05-01), поэтому необходимо указать тип данных в виде строки. Если тип данных указан как DateTime, при сериализации данные в XML-файле будут выглядеть как yyyy-MM-ddTHH:mm:ss (например: 2021-05-01T00:00:00)

.

Класс: JpkFakturaCtrl

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

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

Класс: 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; }
}

Класс: JpkFakturaWierszCtrl

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

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

Класс: 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; }
}

Примечание. В приведенном выше коде вы увидите свойства: DataDoDt и DataOdDt. Это общедоступные свойства, содержащие значения DataDo и DataOd соответственно, как DateTime. При указании [XmlIgnore] это свойство будет игнорироваться во время десериализации/сериализации. В XML формат данных — yyyy-MM-dd (пример: 2021-05-01), поэтому необходимо указать тип данных в виде строки. Если тип данных указан как DateTime, при сериализации данные в XML-файле будут выглядеть как yyyy-MM-ddTHH:mm:ss (пример: 2021-05-01T00:00:00)

.

Класс: 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; }
}

Класс: 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
}

Класс: 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
}

Обратите внимание, что в приведенном выше коде указано пространство имен.

Класс: 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");
Maurice Klimek
7 июля 2021 в 21:12
0

На самом деле, это десятичное число должно было быть десятичным, а не строкой ;-)

Maurice Klimek
7 июля 2021 в 21:18
0

Удаление new XmlRootAttribute("JPK") и добавление пространства имен к подклассам помогло.