I'm new in C# developpment and I want to know the procedure to get one CS file for each XSD schema I have.
I have 3 xsd files (A.xsd, B.xsd and Common.xsd). Both A and B have Common as import. I've tried "xsd.exe" and "xsd2code.exe" without success.
"xsd.exe"
Cannot generate classes because no top-level elements with complex type were found into "Common.xsd".
Files "A.cs" and "B.cs" are generate but the code of "Common.xsd" is in each files.
"xsd2code.exe"
"Common.cs" is well generated with the namespace I've choosen, "MyNamespace.Common".
Other files could not be generated because of unspecified types however I use the "MyNamespace.Common" as custom usings ("/cu" option).
Does someone have an idea?
Thanks in advance.
You need to reference all the schemas that are in the import or include chain.
Try this:
xsd /c A.xsd B.xsd Common.xsd
Edit: However this will mean that all the classes are in one file.
If you want them split out into different files you have two options:
Manually split them out. I know this is a generated file but if your source schemas are fairly static then it's a one off exercise.
Use svcutil.exe instead. However this is much more complicated and actually you may not even be able to do this unless your schemas all abide by certain guidelines. If you are interested see below for the process.
If you fancy option 2 above then here is the general process:
Extract the types from Common.xsd using the /dconly flag on svcutil. This will generate a class file with your common types.
Compile this class into an assembly
Extract the types from A.xsd using the /r flag and referencing your CommonTypes.dll assembly.
Do the same for B.xsd
However, this approach is based on svcutil using the DataContractSerializer to do the work, as the /r flag is not available to XmlSerializer. And this will only work if the your schemas adhere to the rather strict DCS rules (can be found here: http://msdn.microsoft.com/en-us/library/ms733112.aspx).
If these rules are not adhered to then svcutil will fall back to using XmlSerializer which does not support /r flag.
Hope this helps.
Related
i have a peice of code that outputs many different XML files using the DataContractSerializer
i would like to be able to output an XSL and XSD along with each one.
this is purely for learning purposes.
Also I have not included any code as i think it is a fairly generic question.
the only way i have found to do this so far is by using the svcutil.exe.
Is the datacontractserialiser able to do this at runtime?
(or is my understanding of the XSD and XSL incorrect?)
Having done a bit more reading i understand that the XSL needs to be defined for the XML not along with it and is something that needs to be done by me manually.
Edit: I have the Svcutil working i was however wondering if it was possible to do this in code. (ultimately i would like to place a copy of the XSD in the same place as the XML file)
You can extract the XSD from the DataContract using svcutil.exe
svcutil.exe /dataContractOnly *.dll
Docu:
http://msdn.microsoft.com/en-us/library/aa702581.aspx
Edit:
To do this at runtime use the XsdDataContractExporter
I have a XSD file, from which I want to generate C# and Java classes as well.
I first set the namespace in the XSD according to my C# namespace where my classes resides. The generation (with the Microsoft tools) works fine and also the serialisation works great and I can validat them against the XSD - perfect.
Now I want to create java classes with JAXB.
The problem is that the classes which are going to be created have a different package structure then the one in C#. So when I set the XSD namespace to the package structure of java, it works fine. I can serialize and validate the XML.
Now my question(s):
Is there a way to solve this? (Have one XSD for both generation tools)
Do I lack a understanding of what the namespace actually is needed for?
Thank you
Edit: Since it seems to be that there is a missunderstanding, I added an example
XSD: targetNamespace = "http://foo.bar/mySubNs/model"
C# Modelnamespace: com.foo.mySubNs.model (which fits the XSD namespace)
all generated classes will have the same namespace provided though the MS codegen
Java Modelnamespace : com.foo.myOtherSubNs.model (which differs from the XSD namespace)
the generated classes will have the "C# namespace". As a result the classes will not compile.
If I would change the namespace during the code generation for java, I can compile the classes. So far so good. But I won't be able to validate the generated XML by that java classes against the XSD, since the namespace differs.
To marshall my objects in Java, I use JAXB like this:
ValidationEventCollector validationCollector = new ValidationEventCollector();
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new File ("my/schema/location"));
// JAXB_CONTEXT is just an instance of "JAXBContext"
Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
marshaller.setSchema(schema);
marshaller.setEventHandler(validationCollector);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
JAXBElement<MyClass> root = new JAXBElement<MyClass> ( new QName(MyClass.class.getPackage().getName(),"MyClass"),MyClass.class, node);
marshaller.marshal(root, new File("output/Path/obj.xml"));
To build my java classes from the schema I use a xjc-task in an ant build script:
<xjc destdir="${dir.src.gen}" removeOldOutput="no" extension="true">
<schema dir="${dir.schema}" includes="${file.schema}"/>
<binding dir="${dir.schema}" includes="*.xjb"/>
<produces dir="${dir.src.gen}" includes="**/*.java"/>
</xjc>
The XSD namespace doesn't have to match the package structure, at least not in Java. When generating the classes using JAXB just provide the package you want to put the classes into.
You must take your pick as to what model is the main one: XSD, C#, or Java code. Once you make that choice, you must let the other two vary as they may. The best choice would be to make your XSD the reference model, generate the code in both languages with their respective tools, and just accept the results.
You can also try to pick the XML namespace such that the code at both ends will be satisfactory, but don't try to force anything to the last letter. That's not how it's meant to work.
I am trying to generate C# classes from the following XSD file.
I run xsd.exe with the options to generate C# classes. Ideally I would like to create an ORM from the XSD (and thus generate the DDL from the schema file), but I am not sure if XSD.exe is the way to go forward.
In any event, this is what I want to do (in decreasing order of urgency)
Create classes from the XSD file
Provide CRUD functionality (active record pattern) via an (autogenerated?) ORM
Autogenerate DDL from the XSD and populate the db with the permitted values specified in the XSD.
For the last one, I suspect that I may have to hack something together using XSLT.
Starting with the first problem, I run xsd.exe like this:
xsd mddl.xsd /c /eld /o: c:\some\folder
The output from running the above command is:
- Group 'mathNode.model' from targetNamespace='http://www.mddl.org/mddl/3.0-beta' has invalid definition: Circular group reference.
Now I am new to XML/XSD etc - so I am currently stuck on how to resolve this. Can someone spot why the Circular reference is being caused - and more importantly, how to fix it?
You may have already seen this; it complains of the same issue, and the answers suggest hand-creating the classes to handle the serialization. Doesn't seem like a great thing to me, but there you go.
I'm running into the same problem with a schema we've been given, and researching other tools that might be able to handle this. There's conflicting information as to whether this is actually valid from an XML Schema standpoint; most people think that it is (though MS disagrees: link).
For my application, I need to serialize data to file using XML, so I read Introducing XML Serialization on MSDN. One thing that concerns me is under the Security Considerations for XmlSerializer Applications section it reads:
The XmlSerializer creates C# (.cs)
files and compiles them into .dll
files in the directory named by the
TEMP environment variable;
serialization occurs with those DLLs.
A user may have multiple instances of my application running at the same time. My concern is that the 2 different instances will be serializing to different XML files, however, the XmlSerializer class in application instance 2 could over write the DLLs generated by the XmlSerializer class in application instance 1. Should this be a concern, or are temp/unique file names used for these DLL names?
FYI: I need to use XML instead of binary serialization as we need to edit values in the files by hand sometimes.
Thanks
Should this be a concern, or are temp/unique file names used for these DLL names?
The names are unique, you don't need to worry about that
If your app is going to make extensive use of XML serialization, you might want to pre-generate the serialization assembly using Sgen.exe. This will avoid the overhead of generating it at runtime, and the assembly name will be fixed (YourAssembly.XmlSerializers.dll)
The following questions are about XML serialization/deserialization and schema validation for a .net library of types which are to be used for data exchange.
First question, if I have a custom xml namespace say "http://mydomain/mynamespace" do I have to add a
[XmlRoot(Namespace = "http://mydomain/mynamespace")]
to every class in my library. Or is there a way to define this namespace as default for the whole assembly?
Second question, is there a reason behind the always added namespaces
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
even if there is no actual reference to any of the namespaces? I just feel they add noise to the resulting xml. Is there a way to remove them an only have the custom namespace in the resulting xml?
Third question, are there tools to support the generation of schema definitions (e.g. for all public [Serializable] classes of an assembly) and the validation of xml against specific schemas available?
If there are, would you recommend XML Schema from W3C or RELAX NG?
Just to add - the "xsi" etc is there to support things like xsi:nil on values later on - a well-known pattern for nullable values. It has to write the stream "forwards only", and it doesn't know (when it writes the first bit) whether it will need nil or not, so it assumes that writing it unnecessarily once is better than having to use the full namespace potentially lots of times.
1) XmlRoot can only be set at the class/struct/interface level (or on return values). So you can't use it on the assembly level. What you're looking for is the XmlnsDefinitionAttribute, but I believe that only is used by the XamlWriter.
2) If you're worried about clutter you should avoid xml. Well formed xml is full of clutter. I believe there are ways to interract with the xml produced by the serializer, but not directly with the XmlSerializer. You have much more control over the XML produced with the XmlWriter class. Check here for how you can use the XmlWriter to handle namespaces.
3) XSD.exe can be used to generate schemas for POCOs, I believe (I've always written them by hand; I may be using this soon to write up LOTS, tho!).
Tools,
- xsd.exe, with a command line like
xsd /c /n:myNamespace.Schema.v2_0 myschema_v2_0.xsd
I put the schema in a separate project.
liqudXML which is useful if there are several schemas, or you want full support of the schema features (DateTimes with offsets, positive/Negative decimals,), and cross platform generation.