Building different XML files with same JAXB objects - java

Let's say I want to use JAXB to generate two XML files -- one containing a list of items, the other containing detailed definitions of those items. For instance, something like this:
Garage.xml:
<garage>
<car ref="1" />
<car ref="2" />
</garage>
Cars.xml:
<cars>
<car id="1" color="blue" model="Impreza" />
<car id="2" color="plaid" model="Taurus" />
</cars>
Is there anything clever I can do to define a single JAXB Car.java object that will allow me to use the same object for both files? If not, is there an accepted best practice anyone would recommend beyond the obvious solution of creating two separate Car classes? (One with the ref attribute, the other with the id, color, and model attributes.)

Related

Generate Java class from custom model

Generate java file from XML file without any API
Hi, I would like to know if it's possible to generate a java class from existing model as illustrate in this picture below.enter image description here
Informations about the generated class will be found in a XML file like this:
<?xml version="1.0" encoding="UTF-8"?>
<entity name="Balise1">
<attribut name="a" type="List" basetypeid="1"/>
<typedef type="List" basetypeid="2" id="1"/>
<typedef type="String" id="2"/>
</entity>
For exemple when I find the tagname "entity" I create a instance of MjEntity and so on. After iterating the XML file, I have just to generate my Java class.
I believe a costum XML format reader requires you to write your own generator.
There are formats that can generate Java classes from XML. Take a look at .XSD -> .java here..
Generate Java classes from .XSD files...?
Also, if you dont want entity relations in the class object, you can create an orm.xml (Object Relation Mapping) to define this. Take a look at
https://dzone.com/articles/persisting-entity-classes

Include tag in jaxb

I have an xml file of following structure:
<root>
<paramsToInclude>
<params id="id1">
<param11>val1</param11>
<param12>val2</param12>
<param13>val3</param13>
<param14>val4</param14>
</params>
<params id="id3">
<param31>val1</param31>
<param32>val2</param32>
</params>
</paramsToInclude>
<process>
<subprocess1>
<include params="id1"/>
<query>
SELECT *
FROM
table;
</query>
</subprocess2>
<subprocess1>
<rule>rule1</rule>
<rule>rule2</rule>
</subprocess2>
<subprocess3>
<processParam>val1</processParam>
<include params="id2"/>
<include params="id3"/>
</subprocess3>
</process>
I'm using jaxb to parse this xml into the java classes. Is there a way to substitute includes in the process by it's values from the begin of file? I mean, I wan't file to be parsed as if it look's like
<root>
<paramsToInclude>
<params id="id1">
<param11>val1</param11>
<param12>val2</param12>
<param13>val3</param13>
<param14>val4</param14>
</params>
<params id="id3">
<param31>val1</param31>
<param32>val2</param32>
</params>
</paramsToInclude>
<process>
<subprocess1>
<param11>val1</param11>
<param12>val2</param12>
<param13>val3</param13>
<param14>val4</param14>
<query>
SELECT *
FROM
table;
</query>
</subprocess2>
<subprocess1>
<rule>rule1</rule>
<rule>rule2</rule>
</subprocess2>
<subprocess3>
<processParam>val1</processParam>
<param11>val1</param11>
<param12>val2</param12>
<param13>val3</param13>
<param14>val4</param14>
<param31>val1</param31>
<param32>val2</param32>
</subprocess3>
</process>
is it possible t do this? I've found link http://thetechietutorials.blogspot.com/2011/08/jaxb-tutorial-part-2-jaxb-with-xinclude.html how to this include from another file, but comment says that it's impossible to do this for the same file (I understand that I can put this includes in another xml, but I don't think it's a best way). Also I don't want to use hashMap because in this way included params will be stored in hashMap and processParam (from subprocess3) will be class variable.
Is there a way to do this somehow?

is it possible with JAXB to marshal two or more elements into one domain object field?

I have two different XML structures I'd like to map to one domain object. I'm using MOXy's external binding support so I can choose which binding to use dynamically.
Here's my question. I have an XML structure like the one below:
<entity>
<compoundID_one>foo</compoundID_one>
<compoundID_two>bar</compoundID_two>
</entity>
I'd like to have a single List<String> field in my domain class which would contain 'foo' and 'bar'
I've tried this:
...
<java-attributes>
<xml-elements>
<xml-element java-attribute="idList" name="compoundID_one" />
<xml-element java-attribute="idList" name="compoundID_two" />
</xml-elements>
</java-attributes>
...
but I just get null for the field in the domain object. If I omit the xml-elements wrapper I only get one of the compoundID's in the list.
I found this question which seems to suggest this should work. Am I doing something wrong or is there a better way to do this?
I just had the binding XML wrong, it should be:
...
<java-attributes>
<xml-elements java-attribute="idList">
<xml-element name="compoundID_one" />
<xml-element name="compoundID_two" />
</xml-elements>
</java-attributes>
...
All works fine now.

How to split xml to header and items using smooks?

I have a xml file roughly like this:
<batch>
<header>
<headerStuff />
</header>
<contents>
<timestamp />
<invoices>
<invoice>
<invoiceStuff />
</invoice>
<!-- Insert 1000 invoice elements here -->
</invoices>
</contents>
</batch>
I would like to split that file to 1000 files with the same headerStuff and only one invoice. Smooks documentation is very proud of the possibilities of transformations, but unfortunately I don't want to do those.
The only way I've figured how to do this is to repeat the whole structure in freemarker. But that feels like repeating the structure unnecessarily. The header has like 30 different tags so there would be lots of work involved also.
What I currently have is this:
<?xml version="1.0" encoding="UTF-8"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:calc="http://www.milyn.org/xsd/smooks/calc-1.1.xsd"
xmlns:frag="http://www.milyn.org/xsd/smooks/fragment-routing-1.2.xsd"
xmlns:file="http://www.milyn.org/xsd/smooks/file-routing-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
</params>
<frag:serialize fragment="INVOICE" bindTo="invoiceBean" />
<calc:counter countOnElement="INVOICE" beanId="split_calc" start="1" />
<file:outputStream openOnElement="INVOICE" resourceName="invoiceSplitStream">
<file:fileNamePattern>invoice-${split_calc}.xml</file:fileNamePattern>
<file:destinationDirectoryPattern>target/invoices</file:destinationDirectoryPattern>
<file:highWaterMark mark="10"/>
</file:outputStream>
<resource-config selector="INVOICE">
<resource>org.milyn.routing.io.OutputStreamRouter</resource>
<param name="beanId">invoiceBean</param>
<param name="resourceName">invoiceSplitStream</param>
<param name="visitAfter">true</param>
</resource-config>
</smooks-resource-list>
That creates files for each invoice tag, but I don't know how to continue from there to get the header also in the file.
EDIT:
The solution has to use Smooks. We use it in an application as a generic splitter and just create different smooks configuration files for different types of input files.
I just started with Smooks myself. However... your problem sounds identical to this: http://www.smooks.org/mediawiki/index.php?title=V1.5:Smooks_v1.5_User_Guide#Routing_to_File
You will have to provide the output FTL format in whole, that's the downside of using a general purpose tool I guess. Data mapping often includes a lot of what feels like redundancy, one way around this is to leverage convention but that has to be built into the framework.
I don't know smooks, but the simplest solution (with poor performance) would be (to create the Nth file):
copy the whole xml structure
delete all the invoice tags but the Nth one
I don't know how to do that in smooks, that only an idea. In this case you don't need to duplicate the structure of the xml in a freemarker template.

Java replace in XML-file

I have created my own XML-file on my Android phone, which looks similar to this
<?xml version="1.0" encoding="utf-8" ?>
<backlogs>
<issue id="1">
<backlog id="0" name="Linux" swid="100" />
<backlog id="0" name="Project Management" swid="101" />
</issue>
<issue id="2">
<backlog id="0" name="Tests" swid="110" />
<backlog id="0" name="Online test" swid="111" />
<backlog id="0" name="Test build" swid="112" />
<backlog id="0" name="Update" swid="113" />
</issue>
</backlogs>
I have then converted it into a String to replace inside the string using Regular Expression, but I have a problem with the Regular Expression. The Regular Expression I just created looks like this
([\n\r]*)<(.*)issue(.*)1(.*)([\n\r]*)(.*)([\n\r]*)(.*)([\n\r]*)(.*)<(.*)/(.*)issue(.*)
I need to replace the specific issue-tag (located with the specific ID) with another issue-tag in another String
The Regular Expression works fine for the tag with ID 1, but not with ID 2 as there is another amount of tags, but is there any way to get around the use of amount?
I hope you understand my question
I finally found a solution for my question, which is
([\n\r]*)<(.*)issue(.*)1[\S\s]*?<(.*)/(.*)issue(.*)
Do not use regex. Please. Use XML parser.
Do you know what is the highest voted SO answer
Use a SAX (or StAX) parser and writer at the same time.
As you read one event, detect whether to write the same event type to the writer without modification, or to do some modifications in the state you are currently in - like swapping an element name or attribute value. This will handle an unlimited amount of elements at the expense of CPU usage; in general it will be pretty light-weight.

Categories

Resources