反序列化自定义 XML 时出现 InvalidOperationException(缺少命名空间)
Posted
技术标签:
【中文标题】反序列化自定义 XML 时出现 InvalidOperationException(缺少命名空间)【英文标题】:InvalidOperationException when deserializing custom XML (lack of namespace) 【发布时间】:2021-09-13 19:57:04 【问题描述】:我有一个以以下根开头的 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
我通过互联网进行查询:
I ensured that the XmlRoot element has the exact capitalized version I encounter in the file I put the namespace in I tried adding Serializable, no changes I ensured I pass the XmlRootAttribute to the serializer constructor我的蜘蛛感觉告诉我它可能与第二个定义有关,但我不确定如何处理它。我试图删除它(出于科学目的),但它并没有改变响应。
我还有什么遗漏的吗?
剧透警告:这(也)是关于第二个命名空间定义的。值得庆幸的是,接受的答案向我展示了如何声明它,以及如何处理 etd
部分。那,以及从代码中删除new XmlRootAttribute("JPK")
。
【问题讨论】:
您的代码太少而无用。请提供完整的有效示例 XML 文件,而不仅仅是第一行。 已添加。希望这会有所帮助。 【参考方案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 语句是必需的:
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 序列化很有用。
创建测试数据
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");
【讨论】:
事实上,该小数被假定为小数,而不是字符串;-) 删除new XmlRootAttribute("JPK")
并将命名空间添加到子类就可以了。以上是关于反序列化自定义 XML 时出现 InvalidOperationException(缺少命名空间)的主要内容,如果未能解决你的问题,请参考以下文章
如何自定义 SpringWebFlux WebClient xml+rss JAXB 反序列化?
Spring Boot:使用自定义序列化器 + 反序列化器消费和生成 XML
Newtonsoft.Json.JsonSerializationException:'反序列化对象时出现意外标记:使用动态对象注释
如何从不使用 XElement 的自定义 XML 序列化/反序列化为 `Dictionary<int, string>`?