Code Generator that writes code to generate and XML doc structure? [modified]
-
Hello, Has anyone ever seen/created such an animal? I'm looking for a sample of a code generator that will generate code (preferably one that uses C# and the XMLTextWriter) to create an XML document structure based on an XML file as input. I have to build some classes that allow me to generate some very complex/large/nasty XML documents for use in B2B exchange of data (like invoices, orders, etc.). A third party has dictated the structure and provided example XML documents. Instead of hand coding these classes, I'd like to be able to automatically generate them by using these example XML documents as input. This seems like a fairly easy task but I haven't sun across a demonstration of this yet. An Example XML file (contents): =============================== . . . . . . Example output from the code generator that takes the path of the xml file above (this is merely a simple example): ================================================== // instantiate XmlTextWriter over file stream using UTF-8 XmlTextWriter tw = new XmlTextWriter(fileName, Encoding.UTF8); // specify serialization details tw.Formatting = Formatting.Indented; tw.Indentation = 8; tw.QuoteChar = '\"'; // No need for a start element //tw.WriteStartDocument(); tw.WriteStartElement("myRootNode"); tw.WriteStartElement("myChildNode1"); tw.WriteStartElement("myChildNode2"); tw.WriteAttributeString("", "myAttribute1", "", "test"); tw.WriteEndElement(); // myChildNode2 tw.WriteEndElement(); // myChildNode1 tw.WriteEndElement(); // myRootNode // No need for a start element //tw.WriteEndDocument(); // close the stream tw.Close(); Thanks for your time and input, Josh Blair Evergreen, CO -- modified at 13:00 Thursday 25th May, 2006
I think I understand what you're talking about, although it doesn't make much sense. You take an XML document as input and create the code that will generate that XML document. I've never seen anything like that before, but I'm pretty sure you could just write one yourself using an XmlReader and a StringBuilder (or better yet - CodeDom).
-
Josh Blair wrote:
I must not be stating the problem and desired results appropriately.
Yes I still don't get it. Based on your latest post I still think your Goal is: 1) Generate XML data from ODBC data source Is that correct? If it is correct then yes I do believe it is possible that you are not taking advantage of the .NET Frameworks inherent power to accomplish this. The Library has very rich capacity to connect and consume Database data. Just as powerful are the XML libraries such as the XmlSerializer that I mentioned.
"What classes are you using ? You shouldn't call stuff if you have no idea what it does"
Christian Graus in the C# forumled mike
led mike, To answer #1, let me use an example: lets take an invoice...yes some of the data comes from an ODBC datasource (ERP system), but only some of the data. Other portions of the data come from other sources of data as well (config files, other data sources like SQL Server, etc.). I've used serialization in a limited capacity for things like reading and saving application configuration settings and such. Are you saying that I should build business objects that are serializable? As in an Invoice object that is serializable so I can instantiate the object, fill it's properties, call it's methods and thn have the ability to serialize it to produce an XML document from this business object? Thanks again for the clarification, Josh Blair Evergreen, CO
-
led mike, To answer #1, let me use an example: lets take an invoice...yes some of the data comes from an ODBC datasource (ERP system), but only some of the data. Other portions of the data come from other sources of data as well (config files, other data sources like SQL Server, etc.). I've used serialization in a limited capacity for things like reading and saving application configuration settings and such. Are you saying that I should build business objects that are serializable? As in an Invoice object that is serializable so I can instantiate the object, fill it's properties, call it's methods and thn have the ability to serialize it to produce an XML document from this business object? Thanks again for the clarification, Josh Blair Evergreen, CO
Here is something that might help: different portions of the xml document(s) will come from different sources of data. Again taking an invoice as an example (but there are other types of docments as well): I have to send invoices to a third party. This third party defined the xml structures that I have to populate and did not provide schemas or DTDs. A large portion of the data that I need to send to this thord party will originate from a legacy ERP system that does offer an ODBC driver. I can obtain the data from this system, no problem...already got that part licked. The invoice XML document has a "header section" which contains sub-sections like "ship-to section", "buyer section" and so on nested within the "header section". It also contain a "line item section" where there can be one to many line items in this section. Some of the data that populates the "header section" will come from the invoice header in the ERP system (via ODBC). Other parts will come from a configuration file, while other data will come from database tables not originating from the ERP system (maybe a SQL Server). Most of the data that will populate the "line item section" will come from the ERP system from the lines on the invoice. Serialization might be the proper approach. I think the code generator that I wrote may be misusing the .NET framework because it is essentially reproducing the features of serialization. BUT...when using serialization, bdo you have full control over how things get serialized? I can't have all the "junk" that comes with serialization out of the box. When I say "junk", I mean the xml namespaces and extra crap not allowed by this third party. As in: xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Also, I need to have full control over the order of how elements are ordered and nested. Is this possible with .NET serialization? I'd rather not have to transform the serialized business object before I send it off because I'm not really versed at XSLT. Josh Blair Evergreen, CO
-
I think I understand what you're talking about, although it doesn't make much sense. You take an XML document as input and create the code that will generate that XML document. I've never seen anything like that before, but I'm pretty sure you could just write one yourself using an XmlReader and a StringBuilder (or better yet - CodeDom).
Yes, the output from the code generator alone doesn't offer much by itself. So then, once I have the code that produces the XML document (an empty version with no invoice data), I add to that code. I add public properties with get and set accessors. I add the ablity to add line items to a "line itme collection", things like that. So from my code, I can grab all the data necessary that will eventually populate this document, then I instantiate this xml invoice business object filling its properties, collections, etc. Then i call a "create" method which generates a new xml document with the proper structure containing all the invoice data from my ERP system and other data sources. Am I approaching this bass-ackwards? Thanks, Josh Blair Evergreen, CO
-
led mike, To answer #1, let me use an example: lets take an invoice...yes some of the data comes from an ODBC datasource (ERP system), but only some of the data. Other portions of the data come from other sources of data as well (config files, other data sources like SQL Server, etc.). I've used serialization in a limited capacity for things like reading and saving application configuration settings and such. Are you saying that I should build business objects that are serializable? As in an Invoice object that is serializable so I can instantiate the object, fill it's properties, call it's methods and thn have the ability to serialize it to produce an XML document from this business object? Thanks again for the clarification, Josh Blair Evergreen, CO
-
Yes, the output from the code generator alone doesn't offer much by itself. So then, once I have the code that produces the XML document (an empty version with no invoice data), I add to that code. I add public properties with get and set accessors. I add the ablity to add line items to a "line itme collection", things like that. So from my code, I can grab all the data necessary that will eventually populate this document, then I instantiate this xml invoice business object filling its properties, collections, etc. Then i call a "create" method which generates a new xml document with the proper structure containing all the invoice data from my ERP system and other data sources. Am I approaching this bass-ackwards? Thanks, Josh Blair Evergreen, CO
Maybe this article would be helpful? Generate Classes From Declarative Code[^]
-
Here is something that might help: different portions of the xml document(s) will come from different sources of data. Again taking an invoice as an example (but there are other types of docments as well): I have to send invoices to a third party. This third party defined the xml structures that I have to populate and did not provide schemas or DTDs. A large portion of the data that I need to send to this thord party will originate from a legacy ERP system that does offer an ODBC driver. I can obtain the data from this system, no problem...already got that part licked. The invoice XML document has a "header section" which contains sub-sections like "ship-to section", "buyer section" and so on nested within the "header section". It also contain a "line item section" where there can be one to many line items in this section. Some of the data that populates the "header section" will come from the invoice header in the ERP system (via ODBC). Other parts will come from a configuration file, while other data will come from database tables not originating from the ERP system (maybe a SQL Server). Most of the data that will populate the "line item section" will come from the ERP system from the lines on the invoice. Serialization might be the proper approach. I think the code generator that I wrote may be misusing the .NET framework because it is essentially reproducing the features of serialization. BUT...when using serialization, bdo you have full control over how things get serialized? I can't have all the "junk" that comes with serialization out of the box. When I say "junk", I mean the xml namespaces and extra crap not allowed by this third party. As in: xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Also, I need to have full control over the order of how elements are ordered and nested. Is this possible with .NET serialization? I'd rather not have to transform the serialized business object before I send it off because I'm not really versed at XSLT. Josh Blair Evergreen, CO
It sounds to me like you could use a DataSet to coalesce the disparate sources. See some DataSet articles I know there are some on CodeProject.
Josh Blair wrote:
I need to have full control over the order of how elements are ordered and nested.
A DataSet fulfills that requirement. You can design the tables and relationships to your requirements.
Josh Blair wrote:
BUT...when using serialization, bdo you have full control over how things get serialized?
Yes there are several different ways to control serialization.
Josh Blair wrote:
When I say "junk", I mean the xml namespaces and extra crap not allowed by this third party. As in: xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance".
That makes no sense at all, those are XML standard namespaces. :~ Anyway that should be possible one way or another. I expect you can control that using declarative attributes in your code. Look at the XmlSerializer and the XmlRootAttribute attribute.
-
Maybe this article would be helpful? Generate Classes From Declarative Code[^]
Dustin, thanks for the link. That is a pretty cool app. I tried it with my XML structures and it fails. I tweaked the app and my XML a bit an got it to run. That is a great sample. I'll see if the output is going to be useful and let you know. I also tried running XSD.exe (mentioned in one of the comments to the article) over my XML samples. Here is the output: C:\Projects\Customer_XMLCodeGenerator_CS>xsd CustomerDespatchAdvice.xml Microsoft (R) Xml Schemas/DataTypes support utility [Microsoft (R) .NET Framework, Version 1.1.4322.573] Copyright (C) Microsoft Corporation 1998-2002. All rights reserved. Error: There was an error processing 'CustomerDespatchAdvice.xml'. - The same table (Country) cannot be the child table in two nested relations. (In this xml sample, there are multiple sections with the same element (Country), and the tool treats those as "tables" and 2 tables can't have the same name...) I have run into this type of error before with other XML-based projects. I think what is basically going on is that the XSD tool determines that the XML data is not valid according to the ADO.NET schema inference rules. See the following article for more on this issue. Quite a limitation if you ask me. Not a big deal if you have the luxury of defining the XML data from the beginning but not cool if you are forced to use someone elses structure... I had the same problem with cXML (http://www.cXML.org in another similar project) http://support.microsoft.com/default.aspx?scid=kb;EN-US;325696 Anyway, thanks for the tip! Josh Blair Evergreen, CO
-
Dustin, thanks for the link. That is a pretty cool app. I tried it with my XML structures and it fails. I tweaked the app and my XML a bit an got it to run. That is a great sample. I'll see if the output is going to be useful and let you know. I also tried running XSD.exe (mentioned in one of the comments to the article) over my XML samples. Here is the output: C:\Projects\Customer_XMLCodeGenerator_CS>xsd CustomerDespatchAdvice.xml Microsoft (R) Xml Schemas/DataTypes support utility [Microsoft (R) .NET Framework, Version 1.1.4322.573] Copyright (C) Microsoft Corporation 1998-2002. All rights reserved. Error: There was an error processing 'CustomerDespatchAdvice.xml'. - The same table (Country) cannot be the child table in two nested relations. (In this xml sample, there are multiple sections with the same element (Country), and the tool treats those as "tables" and 2 tables can't have the same name...) I have run into this type of error before with other XML-based projects. I think what is basically going on is that the XSD tool determines that the XML data is not valid according to the ADO.NET schema inference rules. See the following article for more on this issue. Quite a limitation if you ask me. Not a big deal if you have the luxury of defining the XML data from the beginning but not cool if you are forced to use someone elses structure... I had the same problem with cXML (http://www.cXML.org in another similar project) http://support.microsoft.com/default.aspx?scid=kb;EN-US;325696 Anyway, thanks for the tip! Josh Blair Evergreen, CO
Glad that helped. We had a similar problem at one of my previous jobs. We wanted to just take their XML format and dump it into a DataSet, but it didn't like the "duplicate" table names. And we couldn't change the format. They ended up creating custom classes that handled the serialization. The problem I had with that solution though was that there wasn't much code generation going on to create those custom classes and there were no unit tests to make sure they worked 100% correct. If there was ever a good place to use code generation...
-
Josh Blair wrote:
Other portions of the data come from other sources of data as well
ahhh... didn't know that. Do these source data schemas change? Why do you keep refering to XmlTextWriter? Do you have some requirement to use it? Why?
led mike, Not sure if these XML structures (schemas) change very often. They come from a company from Japan (from a division in Italy). I think they are pretty solid/permanent. Also, I'm not sure why they didn't provide schemas or DTDs either... I am using the XmlTextWriter only because it is fast (not that speed is really and issue at this point). I used the XMLDocument object in a previous cXML project that was very similar to this project and it seemed a little slower to generate the xml docs. I just wanted to try the XmlTextWriter to see if it was noticably faster. It is also easier to use the XmlTextWriter in my code generator. I also thought about the StringBuilder and it work just as well probably. The XmlTextWriter has a fwe handly features like being able to close off the element and stuff like that. Josh Blair Evergreen, CO