我正在编写一个类来序列化KiCAD BOM /示意图文件。该类工作正常,可以正确地序列化和反序列化原始文件,但是我遇到两个无法解决的小问题。 这是课程代码:
until [ "$(ps -p $pid | grep -c $pid)" = '0' ] || [ $count -gt $kwait ]
# ..... ^^^ ....................... ^^
第一个问题是[XmlRoot(ElementName = "export")]
public class SchematicExport
{
[XmlAttribute]
public const string version = "D";
public Design design { get; set; }
[XmlArrayItem(typeof(Component), ElementName = "comp")]
public List<Component> components;
[XmlArrayItem(typeof(LibPart), ElementName = "libpart")]
public List<LibPart> libparts;
[XmlArrayItem(typeof(Library), ElementName = "library")]
public List<Library> libraries;
[XmlArrayItem(typeof(Net), ElementName = "net")]
public List<Net> nets;
public class Design
{
public string source { get; set; }
public string date
{
get => _date.ToString("dd/MM/yyyy HH:mm:ss");
set => _date = DateTime.Parse(value);
}
private DateTime _date;
public string tool { get; set; }
[XmlElement("sheet")]
public List<Sheet> sheets { get; }
public class Sheet
{
[XmlAttribute]
public int number { get; set; }
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string tstamps { get; set; }
public TitleBlock title_block { get; set; }
public class TitleBlock
{
public string title { get; set; }
public string company { get; set; }
public string rev { get; set; }
public string date
{
get => _date.ToString("yyyy-MM-dd");
set => _date = DateTime.Parse(value);
}
private DateTime _date;
public string source { get; set; }
[XmlElement("comment")]
public List<Comment> comments;
public class Comment
{
[XmlAttribute]
public int number;
[XmlAttribute]
public string value;
public Comment()
{
}
public Comment(int number, string value) : this()
{
this.number = number;
this.value = value;
}
}
public TitleBlock()
{
comments = new List<Comment>();
_date = DateTime.Now;
}
public TitleBlock(string title, string company, string rev, string date, string source)
{
this.title = title;
this.company = company;
this.rev = rev;
this.date = date;
this.source = source;
}
}
public Sheet()
{
title_block = new TitleBlock();
tstamps = DateTime.Now.ToFileTime().ToString("X8");
}
public Sheet(int number, string name) : this()
{
this.number = number;
this.name = name;
}
}
public Design()
{
sheets = new List<Sheet>();
_date = DateTime.Now;
}
public Design(string source, string date, string tool) : this()
{
this.source = source;
this.date = date;
this.tool = tool;
}
}
public class Component
{
[XmlAttribute("ref")]
public string reference { get; set; }
public string value { get; set; }
public string footprint { get; set; }
public string datasheet { get; set; }
[XmlArrayItem(typeof(Field), ElementName = "field")]
public List<Field> fields;
public LibSource libsource { get; set; }
public SheetPath sheetpath { get; set; }
public string tstamp { get; set; }
public class LibSource
{
[XmlAttribute]
public string lib { get; set; }
[XmlAttribute]
public string part { get; set; }
[XmlAttribute]
public string description { get; set; }
}
public class SheetPath
{
[XmlAttribute]
public string names { get; set; }
[XmlAttribute]
public string tstamps { get; set; }
}
public Component()
{
fields = new List<Field>();
libsource = new LibSource();
sheetpath = new SheetPath();
tstamp = DateTime.Now.ToFileTime().ToString("X8");
}
public Component(string reference, string value, string footprint) : this()
{
this.reference = reference;
this.value = value;
this.footprint = footprint;
}
}
public class LibPart
{
[XmlAttribute]
public string lib { get; set; }
[XmlAttribute]
public string part { get; set; }
[XmlArrayItem(typeof(Field), ElementName = "field")]
public List<Field> fields;
[XmlArrayItem(typeof(string), ElementName = "fp")]
public List<string> footprints;
[XmlArrayItem(typeof(Pin), ElementName = "pin")]
public List<Pin> pins;
public class Pin
{
[XmlAttribute]
public string num { get; set; }
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string type { get; set; }
public Pin()
{
}
public Pin(string num, string name, string type) : this()
{
this.num = num;
this.name = name;
this.type = type;
}
}
public LibPart()
{
fields = new List<Field>();
footprints = new List<string>();
pins = new List<Pin>();
}
public LibPart(string lib, string part) : this()
{
this.lib = lib;
this.part = part;
}
}
public class Library
{
[XmlAttribute]
public string logical { get; set; }
public string uri { get; set; }
public Library() { }
public Library(string logical, string uri) : this()
{
this.logical = logical;
this.uri = uri;
}
}
public class Net
{
[XmlAttribute]
public string code { get; set; }
[XmlAttribute]
public string name { get; set; }
[XmlElement("node")]
public List<Node> nodes;
public class Node
{
[XmlAttribute("ref")]
public string reference { get; set; }
[XmlAttribute]
public string pin { get; set; }
public Node() { }
public Node(string reference, string pin) : this()
{
this.reference = reference;
this.pin = pin;
}
}
public Net()
{
nodes = new List<Node>();
}
public Net(string code, string name) : this()
{
this.code = code;
this.name = name;
}
}
public class Field
{
[XmlAttribute]
public string name { get; set; }
[XmlText]
public string value { get; set; }
public Field()
{
}
public Field(string name, string value) : this()
{
this.name = name;
this.value = value;
}
}
public SchematicExport()
{
design = new Design();
components = new List<Component>();
libparts = new List<LibPart>();
libraries = new List<Library>();
nets = new List<Net>();
}
public void Serialze(string filename)
{
XmlSerializer _xmlSerializer = new XmlSerializer(typeof(SchematicExport));
TextWriter _textWriter = new StreamWriter(filename);
_xmlSerializer.Serialize(_textWriter, this);
}
public static SchematicExport Create(string filename)
{
if (!System.IO.File.Exists(filename))
throw new Exception("File not existing");
SchematicExport _schematicExport = null;
XmlSerializer _serializer = new XmlSerializer(typeof(SchematicExport));
StreamReader _reader = new StreamReader(filename);
_schematicExport = (SchematicExport)_serializer.Deserialize(_reader);
return _schematicExport;
}
}
的{{1}}元素。我希望XmlRoot
属性会出现在根XML标记内,但不会:
SchematicExport
第二个问题是元素的顺序(好吧,这不是一个大问题,因为标签不依赖于顺序),我尝试使用version
属性来强制使用它,但是我只得到了多个<export xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
例外。
我只是在序列化程序中做了一些小修改就删除了XmlElement(Order=nn)
和Reflection
:
xmlns:xsi
即使我可以反序列化这样的Xml,我也发现了另一个(更恶意的)问题:
xmlns:xsd
产生的序列化不完整:
public void Serialze(string filename)
{
XmlSerializer _xmlSerializer = new XmlSerializer(typeof(SchematicExport));
XmlSerializerNamespaces _serializerNamespaces = new XmlSerializerNamespaces();
_serializerNamespaces.Add("", "");
using (TextWriter _textWriter = new StreamWriter(filename))
{
_xmlSerializer.Serialize(_textWriter, this, _serializerNamespaces);
}
}
如您所见,?xml version="1.0" encoding="UTF-8"?>
<export version="D">
<design>
<source>C:\Users\m.santucci\Documents\Progetti\Viper\Schede Viper\V1-10A119\V1-10A119.sch</source>
<date>07/03/2019 10:33:01</date>
<tool>Eeschema (5.0.2)-1</tool>
<sheet number="1" name="/" tstamps="/">
<title_block>
<title>V1-10A119</title>
<company>ROB.INT. s.r.l.</company>
<rev>01</rev>
<date>2019-02-25</date>
<source>V1-10A119.sch</source>
<comment number="1" value="Michele Santucci"/>
<comment number="2" value=""/>
<comment number="3" value=""/>
<comment number="4" value=""/>
</title_block>
</sheet>
</design>
<components>
<comp ref="U5">
<value>ADM3101E</value>
<footprint>Analog:LFCSP-12_EP_3x3_Pitch0.5mm</footprint>
<datasheet>https://www.analog.com/media/en/technical-documentation/data-sheets/adm3101e.pdf</datasheet>
<fields>
<field name="Code">820-9369 </field>
<field name="P/N">ADM3101EACPZ-250R7 </field>
<field name="Productor">Analog</field>
<field name="Provider">RS</field>
<field name="manf#">ADM3101EACPZ-250R7 </field>
</fields>
<libsource lib="V1-10A119-rescue" part="ADM3101E-analog" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C83E717</tstamp>
</comp>
<comp ref="C35">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<datasheet>~</datasheet>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AA07</tstamp>
</comp>
<comp ref="C37">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<datasheet>~</datasheet>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AB0B</tstamp>
</comp>
<comp ref="C34">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<datasheet>~</datasheet>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AB65</tstamp>
</comp>
<comp ref="C38">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<datasheet>~</datasheet>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AC22</tstamp>
</comp>
<comp ref="C36">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<datasheet>~</datasheet>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84D1BA</tstamp>
</comp>
</components>
<libparts>
<libpart lib="conn" part="CONN_2">
<description>Symbole general de connecteur</description>
<fields>
<field name="Reference">P</field>
<field name="Value">CONN_2</field>
</fields>
<pins>
<pin num="1" name="P1" type="passive"/>
<pin num="2" name="PM" type="passive"/>
</pins>
</libpart>
</libparts>
<libraries>
<library logical="V1-10A119-rescue">
<uri>C:\Users\m.santucci\Documents\Progetti\Viper\Schede Viper\V1-10A119/V1-10A119-rescue.lib</uri>
</library>
<library logical="conn">
<uri>C:/Users/Public/Documents/Kicad/library/conn.lib</uri>
</library>
</libraries>
<nets>
<net code="200" name="VBUS">
<node ref="P9" pin="2"/>
<node ref="U3" pin="3"/>
<node ref="C12" pin="2"/>
<node ref="C30" pin="2"/>
<node ref="U4" pin="3"/>
</net>
<net code="201" name="Net-(LD13-Pad1)">
<node ref="LD13" pin="1"/>
<node ref="R37" pin="1"/>
</net>
</nets>
</export>
标签(comp部分)和<?xml version="1.0" encoding="UTF-8"?>
<export version="D">
<design>
<source>C:\Users\m.santucci\Documents\Progetti\Viper\Schede Viper\V1-10A119\V1-10A119.sch</source>
<date>07/03/2019 10:33:01</date>
<tool>Eeschema (5.0.2)-1</tool>
<sheet number="1" name="/" tstamps="/">
<title_block>
<title>V1-10A119</title>
<company>ROB.INT. s.r.l.</company>
<rev>01</rev>
<date>2019-02-25</date>
<source>V1-10A119.sch</source>
<comment number="1" value="Michele Santucci"/>
<comment number="2" value=""/>
<comment number="3" value=""/>
<comment number="4" value=""/>
</title_block>
</sheet>
</design>
<components>
<comp ref="U5">
<value>ADM3101E</value>
<footprint>Analog:LFCSP-12_EP_3x3_Pitch0.5mm</footprint>
<fields>
<field name="Code">820-9369 </field>
<field name="P/N">ADM3101EACPZ-250R7 </field>
<field name="Productor">Analog</field>
<field name="Provider">RS</field>
<field name="manf#">ADM3101EACPZ-250R7 </field>
</fields>
<libsource lib="V1-10A119-rescue" part="ADM3101E-analog" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C83E717</tstamp>
</comp>
<comp ref="C35">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AA07</tstamp>
</comp>
<comp ref="C37">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AB0B</tstamp>
</comp>
<comp ref="C34">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AB65</tstamp>
</comp>
<comp ref="C38">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84AC22</tstamp>
</comp>
<comp ref="C36">
<value>100nF</value>
<footprint>Capacitors_SMD:C_0603</footprint>
<fields>
<field name="Code">135-8345 </field>
<field name="P/N">06035G104ZAT2A</field>
<field name="Productor">AVX</field>
<field name="Provider">RS</field>
<field name="manf#">06035G104ZAT2A</field>
</fields>
<libsource lib="V1-10A119-rescue" part="C_Small-Device" description=""/>
<sheetpath names="/MICRO/" tstamps="/5D2A20EE/"/>
<tstamp>5C84D1BA</tstamp>
</comp>
</components>
<libparts>
<libpart lib="conn" part="CONN_2">
<fields>
<field name="Reference">P</field>
<field name="Value">CONN_2</field>
</fields>
<pins>
<pin num="1" name="P1" type="passive"/>
<pin num="2" name="PM" type="passive"/>
</pins>
</libpart>
</libparts>
<libraries>
<library logical="V1-10A119-rescue">
<uri>C:\Users\m.santucci\Documents\Progetti\Viper\Schede Viper\V1-10A119/V1-10A119-rescue.lib</uri>
</library>
<library logical="conn">
<uri>C:/Users/Public/Documents/Kicad/library/conn.lib</uri>
</library>
</libraries>
<nets>
<net code="200" name="VBUS">
<node ref="P9" pin="2"/>
<node ref="U3" pin="3"/>
<node ref="C12" pin="2"/>
<node ref="C30" pin="2"/>
<node ref="U4" pin="3"/>
</net>
<net code="201" name="Net-(LD13-Pad1)">
<node ref="LD13" pin="1"/>
<node ref="R37" pin="1"/>
</net>
</nets>
</export>
(libpart部分)都丢失了。
我无法真正理解错误的出处,但显然问题不是反序列化:
答案 0 :(得分:1)
第一个问题是在XmlRoot
元素上。我希望version
属性会出现在XMLRoot
标记内,但不会出现。
如 Introducing XML Serialization 中所述,XmlSerializer
不会序列化const
成员,即使在公开时也是如此:
XML序列化仅将对象的公共字段和属性值序列化为XML流。 XML序列化不包含类型信息。
XML序列化不会转换方法,索引器,私有字段或只读属性(只读集合除外)。要序列化所有对象的公共和私有字段和属性,请使用DataContractSerializer而不是XML序列化。
解决此问题的最简单方法是为该版本添加代理属性,如下所示:
public const string version = "D";
[XmlAttribute("version")]
[System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
public string Version { get { return version; } set { /* Do nothing */ } }
该属性必须是公共的,但是您可以通过属性Browsable
,EditorBrowsable
和DebuggerBrowsable
降低其可见性。
第二个问题是元素的顺序(好吧,这不是一个大问题,因为标签不依赖于顺序),我尝试使用XmlElement(Order=nn)
属性来强制使用它,但是我得到了许多{{ 1}}例外。
您没有提供此示例,但是我能够重现以下问题。如果我在Reflection
的集合成员的 some 而不是 all 上设置了XmlArrayAttribute.Order
,则会出现以下异常:
SchematicExport
演示小提琴#1 here。
解决方案是遵循异常消息中的建议,并将order属性应用于类中的所有可序列化成员。
因此System.InvalidOperationException: There was an error reflecting type 'SchematicExport'.
---> System.InvalidOperationException: Inconsistent sequencing: if used on one of the class's members, the 'Order' property is required on all particle-like members, please explicitly set 'Order' using XmlElement, XmlAnyElement or XmlArray custom attribute on class member 'nets'.
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
应该类似于:
SchematicExport
请注意,设置元素顺序不仅会在序列化过程中对元素进行重新排序,还会要求,在反序列化过程中它们处于该顺序。
偶然地,您需要在[XmlRoot(ElementName = "export")]
public partial class SchematicExport
{
public const string version = "D";
[XmlAttribute("version")]
[System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
public string Version { get { return version; } set { /* Do nothing */ } }
[XmlElement(Order = 1)]
public Design design { get; set; }
[XmlArray(Order = 2)]
[XmlArrayItem(typeof(Component), ElementName = "comp")]
public List<Component> components;
[XmlArray(Order = 3)]
[XmlArrayItem(typeof(LibPart), ElementName = "libpart")]
public List<LibPart> libparts;
[XmlArray(Order = 4)]
[XmlArrayItem(typeof(Library), ElementName = "library")]
public List<Library> libraries;
[XmlArray(Order = 5)]
[XmlArrayItem(typeof(Net), ElementName = "net")]
public List<Net> nets;
}
中关闭SchematicExport.Serialize(string)
。最简单的方法是通过using
语句:
StreamWriter
您的问题中显示的此方法的第一个版本不执行此操作。
演示小提琴#2 here。