我要使用的布局类似于以下布局(这是较大结构的一部分):

       <Products>
            <R001 Retail=\"2.289\" Rank=\"1\" Code=\"001\" />
            <R002 Retail=\"2.289\" Rank=\"2\" Code=\"002\" />
            <R003 Retail=\"2.889\" Rank=\"3\" Code=\"003\" />
            <R004 Retail=\"0\" Rank=\"4\" Code=\"0\" />
            <R011 Retail=\"0\" Rank=\"7\" Code=\"0\" />
        </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();
        }
    }


使用该代码,这是我不需要的输出:

<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>

最佳答案

对于the docs,将由父元素写入ProductExport的开始和结束元素:


  您提供的WriteXml实现应写出对象的XML表示形式。该框架将编写包装器元素,并在XML编写器启动后对其进行定位。您的实现可以编写其内容,包括子元素。然后,框架关闭包装器元素。


因此,您需要在Products中编写所需的元素名称。最简单的方法是将List<ProductExport>替换为自己的也实现IXmlSerializable的类。

序列化后,框架将已经编写了Product元素(并在之后将其关闭),因此,遵守合同,您所要做的就是编写每个项目的开始和结束元素并委托将其内容写成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();
}


有关有效的演示,请参见this fiddle

10-04 20:31