为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 SGen 为映射到两级数组的 XML 模式生成序列化程序集?

如何使用 SGen 为映射到两级数组的 XML 模式生成序列化程序集?

C#
慕标5832272 2023-09-09 16:26:21
我正在使用需要 XmlSerializerFormat 合约的第三方服务;我想通过创建序列化程序集来加快启动速度,但 Sgen.exe 确实不喜欢 Xsd.exe 为其吐出嵌套数组的架构中的特定构造。该模式包括嵌套两层深度的元素序列,如下所示:Foo.xsd<xs:schema targetNamespace="http://example.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com" elementFormDefault="qualified">    <xs:element name="Foo" type="Foo"/>    <xs:complexType name="Foo">        <xs:sequence>            <xs:element name="List" type="FooList" minOccurs="0" maxOccurs="unbounded"/>        </xs:sequence>    </xs:complexType>    <xs:complexType name="FooList">        <xs:sequence>            <xs:element name="Item" type="FooListItem" minOccurs="0" maxOccurs="unbounded"/>        </xs:sequence>    </xs:complexType>    <xs:complexType name="FooListItem">        <xs:simpleContent>            <xs:extension base="xs:string"/>        </xs:simpleContent>    </xs:complexType></xs:schema>即:一个 toplevelFoo包含多个FooLists,aFooList包含多个FooListItem。运行xsd /c Foo.xsd会产生以下结果:Foo.csusing System.Xml.Serialization;[XmlType(Namespace="http://example.com")][XmlRoot(Namespace="http://example.com", IsNullable=false)]public partial class Foo {    private FooListItem[][] listField;    [XmlArrayItem("Item", typeof(FooListItem), IsNullable=false)]    public FooListItem[][] List {        get {            return this.listField;        }        set {            this.listField = value;        }    }}也就是说,FooList由于某种原因,不存在 for 类,而是只有一个嵌套的FooListItems 数组。然而,当我构建它并仅使用生成的 DLL 运行 Sgen.exe 时sgen /keep obj\Debug\net461\Foo.dll,会出现以下错误消息:错误CS0030:无法将类型“FooListItem []”转换为“FooListItem”错误CS0029:无法将类型“FooListItem”隐式转换为“FooListItem []”因此,Xsd.exe 和 Sgen.exe 似乎试图实现这样一种模式,即元素具有包含 X 项的显式“X 列表”子元素,而无需为列表元素创建单独的类,而仅依赖于序列化的名称合成中间元素的性能;当列表元素本身可能重复时,这种情况就会中断。有办法解决这个问题吗?就像强制 Xsd.exe 为中间元素生成一个类一样?我想这可能是 Xsd.exe 和 Sgen.exe 中的一个实际错误,但这在合理的时间范围内并不能真正帮助我。如上所述,这是第三方服务;我完全无法控制架构,并且对生成代码的手动编辑越少越好,因为我的实际文件有数万行长。
查看完整描述

1 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

错误就在这一行


来自: [XmlArrayItem("Item", typeof(FooListItem), IsNullable=false)]


至:“[XmlArrayItem(“Item”,IsNullable = false)]


这是工作代码的示例:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

using System.Xml.Serialization;


namespace ConsoleApplication1

{

    class Program

    {

        const string FILENAME = @"c:\temp\test.xml";

        static void Main(string[] args)

        {


            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();

            namespaces.Add("xs", "http://www.w3.org/2001/XMLSchema");

            namespaces.Add("", "http://example.com");


            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Indent = true;


            XmlWriter writer = XmlWriter.Create(FILENAME, settings);

            XmlSerializer serializer = new XmlSerializer(typeof(Foo));


            Foo foo = new Foo()

            {

                List = new FooListItem[][] {

                    new FooListItem[] { 

                        new FooListItem() { Value = "abc"},

                        new FooListItem() { Value = "abd"},

                        new FooListItem() { Value = "abe"}

                    },

                    new FooListItem[] { 

                        new FooListItem() { Value = "bbc"},

                        new FooListItem() { Value = "bbd"},

                        new FooListItem() { Value = "bbe"}

                    },

                    new FooListItem[] { 

                        new FooListItem() { Value = "cbc"},

                        new FooListItem() { Value = "cbd"},

                        new FooListItem() { Value = "cbe"}

                    }

                }

            };


            serializer.Serialize(writer, foo, namespaces);




        }

    }

    [XmlType(Namespace = "http://example.com")]

    [XmlRoot(Namespace = "http://example.com", IsNullable = false)]

    public partial class Foo

    {


        private FooListItem[][] listField;


        [XmlArrayItem("Item", IsNullable = false)]

        public FooListItem[][] List

        {

            get

            {

                return this.listField;

            }

            set

            {

                this.listField = value;

            }

        }

    }


    [XmlType(Namespace = "http://example.com")]

    public partial class FooListItem

    {


        private string valueField;


        [XmlText]

        public string Value

        {

            get

            {

                return this.valueField;

            }

            set

            {

                this.valueField = value;

            }

        }

    }



查看完整回答
反对 回复 2023-09-09
  • 1 回答
  • 0 关注
  • 54 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信