One XSD, two code generation tools, two namespaces - c#

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.

Related

How to Generate XSL & XSD from an DataContract object

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

source control \ disadvantage of generating class with XSD

assume this - I want to read and write XML in a predefined scheme - till now it's ok.
The thing is that there is explicit action a developer needs to do case he wants to add another attribute (xsd.exe for example) and it's quite frustrating in teerms of source control (need to check out, generate new file, and check that in).
Is there a way to read xml just by supplying its XSD (without the need to actually auto-generate a class for that?) - in that case if new field will introduce - developer will change only the XSD or something?
Please check the below link,
This can be the solution for this problem.
But please keep in mind that using xsd.exe is robust way to generate the classes for schema.
You can generate the class code form xsd on the fly and you can compile the code and use in your application
How to programmaticly generate .NET classes from XSD? (Like xsd.exe do)
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlcodeexporter
http://msdn.microsoft.com/en-us/library/650ax5cx.aspx

How to get cs files for xml schemas (xsd)

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.

C# : creating classes from XSD file using XSD.exe (help with circular reference in XSD file)

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

Xml Serialization and Schemas in .net (C#)

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.

Categories

Resources