C#XML序列化不包括编写类名
我想要的布局如下所示(这是更大结构的一部分):C#XML序列化不包括编写类名,c#,.net,xml,C#,.net,Xml,我想要的布局如下所示(这是更大结构的一部分): 所以我有一个类,它有一个叫做Products的属性。该属性是我称为ProductExport的类的列表。ProductExport有3个属性,我用XmlAttribute属性标记它们,它们被称为Retail、Rank和Code。在ProductExport中,我实现了IXmlSerializable,因此我可以实现WriteXml(),在其中我将标记名设置为那些R00X标记。不过,由于ProductExport是它自己的类,所以XmlSeria
所以我有一个类,它有一个叫做Products的属性。该属性是我称为ProductExport的类的列表。ProductExport有3个属性,我用XmlAttribute属性标记它们,它们被称为Retail、Rank和Code。在ProductExport中,我实现了IXmlSerializable,因此我可以实现WriteXml(),在其中我将标记名设置为那些R00X标记。不过,由于ProductExport是它自己的类,所以XmlSerializer会为列表中的每个ProductExport编写一个标记。我不想要ProductExport标签。我本以为通过在ProductExport上实现IXmlSerializable,我可以控制ProductExport的所有编写方式,包括不编写它的类名,但事实似乎并非如此。我如何限制写它的类名
public class StoresExport
{
public int ID { get; set; }
public int Name { get; set; }
public string State { get; set; }
public int DistrictID { get; set; }
public int? RegionID { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
public List<CompetitorLocation> RelatedLocations { get; set; }
public List<ProductExport> Products { get; set; }
}
public class ProductExport : IXmlSerializable
{
public float Retail { get; set; }
public int Rank { get; set; }
public string Code { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
// we aren't ever reading just writing
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("R" + Code);
writer.WriteAttributeString("Retail", Retail.ToString());
writer.WriteAttributeString("Rank", Rank.ToString());
writer.WriteAttributeString("Code", Code);
writer.WriteEndElement();
}
}
公共类StoresExport
{
公共int ID{get;set;}
公共int名称{get;set;}
公共字符串状态{get;set;}
public int DistrictID{get;set;}
公共int?RegionID{get;set;}
公共十进制纬度{get;set;}
公共十进制经度{get;set;}
公共列表相关位置{get;set;}
公共列表产品{get;set;}
}
公共类ProductExport:IXmlSerializable
{
公共浮动零售{get;set;}
公共整数秩{get;set;}
公共字符串代码{get;set;}
公共XmlSchema GetSchema()
{
返回null;
}
公共void ReadXml(XmlReader)
{
//我们从不读书,而只是写作
}
public void WriteXml(XmlWriter)
{
writer.writeStart元素(“R”+代码);
WriteAttributeString(“Retail”,Retail.ToString());
WriteAttributeString(“Rank”,Rank.ToString());
WriteAttributeString(“代码”,代码);
writer.writeedelement();
}
}
对于该代码,这是我不想要的输出:
<Products>
<ProductExport>
<R001 Retail=\"0\" Rank=\"1\" Code=\"001\" />
</ProductExport>
<ProductExport>
<R002 Retail=\"0\" Rank=\"2\" Code=\"002\" />
</ProductExport>
<ProductExport>
<R003 Retail=\"0\" Rank=\"3\" Code=\"003\" />
</ProductExport>
<ProductExport>
<R004 Retail=\"0\" Rank=\"4\" Code=\"004\" />
</ProductExport>
<ProductExport>
<R011 Retail=\"0\" Rank=\"7\" Code=\"011\" />
</ProductExport>
</Products>
根据,父元素将写入产品导出的开始和结束元素
:
您提供的WriteXml实现应该写出对象的XML表示框架写入包装器元素,并在启动后定位XML编写器您的实现可以编写其内容,包括子元素然后框架关闭包装器元素
为此,您需要在产品
中写入所需的元素名称。最简单的方法是用您自己的类替换列表
,该类也实现了IXmlSerializable
序列化后,框架将已经编写了产品
元素(之后将关闭它),因此,按照合同,您只需编写每个项目的开始和结束元素,并将其内容的编写委托给IXmlSerializable
的实现:
public class Products : IXmlSerializable, IEnumerable<ProductExport>
{
private readonly List<ProductExport> _products = new List<ProductExport>();
public void Add(ProductExport product) => _products.Add(product);
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
throw new NotSupportedException();
}
public void WriteXml(XmlWriter writer)
{
foreach (var product in this)
{
writer.WriteStartElement("R" + product.Code);
product.WriteXml(writer);
writer.WriteEndElement();
}
}
public IEnumerator<ProductExport> GetEnumerator() => _products.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
<代码>公共类产品:IXmlSerializable,IEnumerable
{
私有只读列表_products=new List();
公共作废添加(ProductExport product)=>\u products.Add(product);
公共XmlSchema GetSchema()=>null;
公共void ReadXml(XmlReader)
{
抛出新的NotSupportedException();
}
public void WriteXml(XmlWriter)
{
foreach(本节中的var乘积)
{
writer.writeStart元素(“R”+产品代码);
product.WriteXml(writer);
writer.writeedelement();
}
}
public IEnumerator GetEnumerator()=>\u products.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()=>GetEnumerator();
}
请参阅,以获得一个有效的演示。我真的不希望在StoreExports类上实现IXmlSerializable,因为其他属性的导出很好,而且它的类型比需要的多,因此如果可能的话,抑制ProductExport标记会更理想。奇怪,因此,在产品中,您将调用WriteXml()的ProductExports实现。所以序列化程序也不会自己调用它,因为ProductExport也实现了Serializer?@user441521框架不会为
产品的任何成员做任何事情,因为您已经通过实现IXmlSerializable
从框架中移除了控制。别误会,这很有效,但我仍然感到困惑。由于我实现了IXmlSerializable,框架正在调用WriteXml()。这是对产品的要求。为什么不在ProductExport上打电话呢?我们明确地从产品中调用它,但我认为框架看到我们也在ProductExport上实现了它,并在那里调用它。所以我认为WriteXml()会被ProductExport调用两次。一次来自框架,因为它看到我们在ProductExport上实现了它,一次来自我们在ProductExport上手动调用它的产品。@user441521框架已将与XmlWriter
的任何和所有交互委托给IXmlSerializable
实现。此时,您可以完全控制为产品的内容编写的内容。你可以完全忽略这些产品;框架在写什么方面不再有发言权,只有你有发言权。我理解这一部分。当我实现IXmlSerializable时,我可以编写我想要的任何东西,但是框架正在调用WriteXml()函数,因为我实现了它
public class Products : IXmlSerializable, IEnumerable<ProductExport>
{
private readonly List<ProductExport> _products = new List<ProductExport>();
public void Add(ProductExport product) => _products.Add(product);
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
throw new NotSupportedException();
}
public void WriteXml(XmlWriter writer)
{
foreach (var product in this)
{
writer.WriteStartElement("R" + product.Code);
product.WriteXml(writer);
writer.WriteEndElement();
}
}
public IEnumerator<ProductExport> GetEnumerator() => _products.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}