Is svcutil.exe a replacement for xsd.exe?

后端 未结 5 912
一生所求
一生所求 2021-01-31 09:44

I am using xsd.exe to generate some c# classes from a .xsd file. I ran into the same issue that is covered here and on other sites where xsd.exe generates Type[] arrays instead

相关标签:
5条回答
  • 2021-01-31 10:31

    Yes, svcutil.exe can be used as a replacement for xsd.exe but it sounds like you are having trouble getting generic collections to be generated. svcutil.exe has a collectionType switch that allows you to specify the type to be used for a collection:

    svcutil /o:Svc.cs /ct:System.Collections.Generic.List`1 http://example.com
    
    0 讨论(0)
  • 2021-01-31 10:37

    Clarification

    Andrew Hare's answer above will work, but the example command that jameswelle pasted just above his last section of code:

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

    does not work because, as stated on MSDN, '. . .the /r and /ct switches for referencing types are for generating data contracts. These switches do not work when using XmlSerializer.'

    HTH.

    0 讨论(0)
  • 2021-01-31 10:42

    I have found Xsd2Code to be much better than xsd.exe does does exactly what you need. See here: http://xsd2code.codeplex.com/

    0 讨论(0)
  • 2021-01-31 10:43

    I would just create your own xsd.exe. Sorry having trouble pasting but if you copy this code into your main:

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

    }

    0 讨论(0)
  • 2021-01-31 10:46

    I have tested the same commands on another schema, ang received similar "junk" results from svcutil. So, the might be a way to make it work like xsd.exe, but so far all Ive seen are far less useful ones.


    Updated answer: I found that many of these generic arrays of xml nodes were replaced by strong types when all the referenced XSD's are forcibly included. In my case, i have many xsd files all referenced by each other, but svcutil doesnt seem to include them. i had to instead tell it to use *.xsd to get them all.

    0 讨论(0)
提交回复
热议问题