我正在使用xsd.exe从.xsd文件生成一些c#类。 我遇到了此处和其他网站上涉及的相同问题,其中xsd.exe生成Type []数组,而不是.xsd文件中类型的通用List集合。 有些人建议如果将/ dataContractOnly参数传递给svcutil.exe,svcutil.exe可以用作xsd.exe的替代品。 但是,似乎这些人都错了,因为svcutil.exe实际上生成了System.Xml.XmlNode []数组属性,而不是基于.xsd文件中的模式创建类型。

例如,给定这个简单的.xsd架构:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
    <xs:complexType name="Employee">
        <xs:all>
            <xs:element name="FirstName" type="xs:string"></xs:element>
            <xs:element name="LastName" type="xs:string"></xs:element>
        </xs:all>
    </xs:complexType>

    <xs:element name="Employees">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element name="Employee" type="Employee"></xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

'xsd.exe / classes Example.xsd'生成:

public partial class Employees {

    private Employee[] employeeField;

    public Employee[] Employee {
        get { return this.employeeField; }
        set { this.employeeField = value; }
    }
}

public partial class Employee {

    private string firstNameField;

    private string lastNameField;

    public string FirstName {
        get { return this.firstNameField; }
        set { this.firstNameField = value; }
    }

    public string LastName {
        get { return this.lastNameField; }
        set { this.lastNameField = value; }
    }
}

'svcutil.exe / target:code / dataContractOnly / serializer:XmlSerializer / importXmlTypes /collectionType:System.Collections.Generic.List`1 Example.xsd'生成:

public partial class Employee : object, System.Runtime.Serialization.IExtensibleDataObject{

    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    private string FirstNameField;

    private string LastNameField;

    public System.Runtime.Serialization.ExtensionDataObject ExtensionData{
        get{ return this.extensionDataField; }
        set{ this.extensionDataField = value; }
    }

    public string FirstName{
        get{ return this.FirstNameField; }
        set{ this.FirstNameField = value; }
    }

    public string LastName{
        get{ return this.LastNameField; }
        set{ this.LastNameField = value; }
    }
}

public partial class Employees : object, System.Xml.Serialization.IXmlSerializable{

    private System.Xml.XmlNode[] nodesField;

    private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("Employees", "http://tempuri.org/XMLSchema.xsd");

    public System.Xml.XmlNode[] Nodes{
        get{ return this.nodesField; }
        set{ this.nodesField = value; }
    }

    public void ReadXml(System.Xml.XmlReader reader){
        this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader);
    }

    public void WriteXml(System.Xml.XmlWriter writer){
        System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes);
    }

    public System.Xml.Schema.XmlSchema GetSchema(){
        return null;
    }

    public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas){
        System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName);
        return typeName;
    }
}
  1. svcutil.exe真的应该是xsd.exe的替代品吗? 产生的输出似乎完全不同。

  2. 此时,看起来我将不得不使用xsd.exe从我的.xsd文件创建类,然后手动调整代码以获得我想要的形式。 我意识到使用纯粹生成的代码是理想的,但我想知道是否有其他人使用xsd.exe作为起点然后在那里工作或者我是否需要考虑另一种方法?

  3. Visual Studio 2010中是否有对xsd.exe的更新?

#1楼 票数:6

是的, svcutil.exe 可以用作xsd.exe的替代品,但听起来你无法生成通用集合。 svcutil.exe有一个collectionType开关,允许您指定要用于集合的类型:

svcutil /o:Svc.cs /ct:System.Collections.Generic.List`1 http://example.com

#2楼 票数:5

澄清

安德鲁·黑尔的回答上面工作,但该jameswelle粘贴刚刚超过他的代码最后一节的示例命令:

svcutil.exe /target:code /dataContractOnly /serializer:XmlSerializer /importXmlTypes /collectionType:System.Collections.Generic.List`1 Example.xsd

工作,因为, 如在MSDN上说 ,”。 用于引用类型的/ r/ ct开关用于生成数据协定。 使用XmlSerializer时,这些开关不起作用。

HTH。

#3楼 票数:2

我只想创建自己的xsd.exe。 很抱歉无法粘贴,但如果您将此代码复制到主要内容中:

        XmlSchemas xsds = new XmlSchemas();
        xsds.Add(xsd);
        xsds.Compile(null, true);
        XmlSchemaImporter schemaImporter = new XmlSchemaImporter(xsds);

        // create the codedom
        CodeNamespace codeNamespace = new CodeNamespace(strNamespace);
        XmlCodeExporter codeExporter = new XmlCodeExporter(codeNamespace);

        List<XmlTypeMapping> maps = new List<XmlTypeMapping>();
        foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values)
        {
            maps.Add(schemaImporter.ImportSchemaType(schemaType.QualifiedName));
        }
        foreach (XmlSchemaElement schemaElement in xsd.Elements.Values)
        {
            maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName));
        }
        foreach (XmlTypeMapping map in maps)
        {
            codeExporter.ExportTypeMapping(map);
        }

        ReplaceArrayWithList(codeNamespace);

        // Check for invalid characters in identifiers
        CodeGenerator.ValidateIdentifiers(codeNamespace);

        // output the C# code
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();

        using (StreamWriter writer = new StreamWriter(strCsPath, false))
        {
            codeProvider.GenerateCodeFromNamespace(codeNamespace, writer, new CodeGeneratorOptions());
        }
    }
    private static void ReplaceArrayWithList(CodeNamespace codeNamespace)
    {
        codeNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
        foreach (CodeTypeDeclaration codeType in codeNamespace.Types)
        {
            foreach (CodeTypeMember member in codeType.Members)
            {
                if (member is CodeMemberField)
                {
                    CodeMemberField field = (CodeMemberField)member;
                    if (field.Type.ArrayRank > 0)
                    {
                        CodeTypeReference type = new CodeTypeReference();
                        type.BaseType = "List<" + field.Type.BaseType + ">";
                        field.Type = type;
                    }
                }
                if (member is CodeMemberProperty)
                {
                    CodeMemberProperty property = (CodeMemberProperty)member;
                    if (property.Type.ArrayRank > 0)
                    {
                        CodeTypeReference type = new CodeTypeReference();
                        type.BaseType = "List<" + property.Type.BaseType + ">";
                        property.Type = type;
                    }
                }
            }
        }
    }

}

}

#4楼 票数:1

我发现Xsd2Code比xsd.exe确实要好得多。 请看这里: http//xsd2code.codeplex.com/

#5楼 票数:1

我在另一个模式上测试了相同的命令,ang收到了来自svcutil的类似“垃圾”结果。 因此,可能是一种让它像xsd.exe一样工作的方法,但到目前为止,我所看到的远没有那么有用。


更新的答案:我发现当强制包含所有引用的XSD时,许多这些xml节点的通用数组被强类型替换。 在我的情况下,我有许多xsd文件都相互引用,但svcutil似乎并没有包含它们。 我不得不告诉它使用* .xsd来获取它们。

  ask by jameswelle translate from so

未解决问题?本站智能推荐:

2回复

Xsd.exe或Svcutil.exe将XSD架构转换为类

是否建议使用svcutil工具而不是xsd工具? 我没有看到这是一个确认的声明,但它确实如此。 我对此感到困惑的原因是我使用这两个工具生成了一个类。 但是,我使用xsd获得了更好的课程。 XSD架构仅由DataContracts组成。 我对svcutil使用了以下命令: 这
1回复

定义了相同实体的多个XSD文件

谢谢你的帮助, 我们有两个XSD文件,它们都共享一些相同的实体,而另一些共享不同的实体。 请注意,具有差异的名称称为不同的名称。 我们想要生成可以序列化/反序列化这些实体的C#代码,而不必以两个在两个不同名称空间中共享相同名称和相同内容的实体结束。 这些就是一个例子。 我们
2回复

使用XSD.exe生成XSD

我在c#中使用AMO构建SSAS多维数据集。 为此,我想获取Server,Cube,Dimension等类的公共属性的列表。这是我的超集,用户必须从中提供强制属性,并可能提供可选属性。 我正在尝试生成XSD架构。 我运行了以下命令 XSD C:\\windows\\assembly
2回复

如何使用带有attributeGroup ref的XSD.exe

我在使用带有ref的attributeGroup时使用xsd.exe时遇到问题。 我用它来生成C#类。 这是我的XSD: 它生成这两个类: 生成的类缺少PersonBaseAttributes Name和Born字段。 我的XSD不正确或xsd.exe不知道如何处理它?
1回复

xsd.exe找不到类型声明

我正在尝试从IRS网站上提供的XSD文件生成类文件: https://www.irs.gov/businesses/corporations/fatca-xml-schemas-and-business-rules-for-form-8966 架构文件可在此处下载: https :
1回复

XSD的属性,以防止XSD.exe FieldSpecified标志

我有一个xsd文件,下面有以下定义。 当使用xsd.exe从xsd文件生成类时,enum attrs会获得一个额外的FieldSpecified属性,如下所示。 除非设置了FieldSpecified属性,否则该值不会使用属性的值进行序列化。 是否有一个额外的属性,我可以添加到xsd或一个
3回复

使用 XSD.exe 的多版本 C# 类/XSD

我正在使用 XSD.exe 将非常复杂的 XML 架构(XSD 文件)转换为 C# 类。 然后我使用 XmlSerializer 将 XML 读入内存并处理数据。 将来,XSD 将发生变化。 所以会有一个新版本。 我将不得不使用 XSD.exe 创建一个新的 cs 文件。 但我仍然希望支持旧版本的
1回复

使用xsd.exe访问从xml生成的类项目

好吧,我使用.net xsd.exe生成了一些类来处理一些xml文件,到目前为止没有问题。 我可以使用XmlSerializaer读取和反类化这些类,并且可以毫无问题地读取大多数itens。 我的问题是,当我到达像波纹管这样的地方时: 我可以访问公共对象“ Item”,但是如何更