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();
}