Dynamic XML creation in Java - java

I am trying to dynamically y create an XML file in Java to display a timetable. I have created a DTD for my XML file and I have an XSL file I would like to use to transform the XML. I don't know exactly how to continue.
What I've tried so far is onClick of some button a Servlet is called which generates the string of the content of the XML file (inserting the dynamic parts of the XML into the String. I now have a String containing the content of the XML file. I would now like to transform the XML file using an XSL file i have on my server and display the result in the page which has called the Servlet (doing this via AJAX).
I'm not sure if I'm in the direction, perhaps I shouldn't even create the XML code in String form from the beginning. So my question is, how do I continue from here? how do I transform the XML string, using the XSL file, and send it as a response to the AJAX call so I can plant the generated code into the page? Or if this is not the way to do it, how do I create a dynamic XML file in a different way producing the same result?

You can use JAXP for this. It's part of standard Java SE API.
StringReader xmlInput = new StringReader(xmlStringWhichYouHaveCreated);
InputStream xslInput = getServletContext().getResourceAsStream("file.xsl"); // Or wherever it is. As long as you've it as an InputStream, it's fine.
Source xmlSource = new StreamSource(xmlInput);
Source xslSource = new StreamSource(xslInput);
Result xmlResult = new StreamResult(response.getOutputStream()); // XML result will be written to HTTP response.
Transformer transformer = TransformerFactory.newInstance().newTransformer(xslSource);
transformer.transform(xmlSource, xmlResult);

Depending on how complicated and large your XML is going to be I would suggest two options. For small, simple structures Java's DOM implementation (Document) will suffice.
If your XML is more elaborate I would look into JAXB. The benefit there is that there are tools that automatically create Java classes from an XML schema (XSD). So you'd have to transform your DTD into an XSD first, but that shouldn't be a problem. You end up with plain data transfer objects (plain objects with getters/setters for the values of the corresponding XML elements) and parsing/encoding plus setting namespaces correctly is done for you. It's quite convenient but can also be a bit of an overkill for simple XML structures.
In both cases, you will end up with a Document instance that you can finally transform using JAXP.

Apache XMLBeans are a nice solution to serializing to and from XML. Here's what you need to do:
Download XMLBeans from http://www.apache.org/dyn/closer.cgi/xmlbeans/binaries
Use the XMLBeans inst2xsd executable (in the bin dir0 to convert your DTD to an XSD
Use the XMLBeans ANT task to convert the XSD into classes which you can use in your app
Here's an example ANT script to use XMLBeans to create the classes:
<project name="my_project" basedir="..">
<property name="my_project.project.path" value="${basedir}"/>
<property name="xbean.dir" value="C:/lib/xmlbeans-2.2.0/lib" />
<path id="classpath">
<fileset dir="${xbean.dir}" includes="**/*.jar" />
</path>
<taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpathref="classpath" />
<xmlbean schema="${testing_project.project.path}/my.xsd" srcgendir="${my_project.project.path}/src-tms-template-filter-fields" classgendir="${my_project.project.path}/bin">
<classpath><path refid="classpath" /></classpath>
</xmlbean>
You'll now have nice Java classes which you can use for clean code to create the XML from the data stored in your DB. Use BalusC's answer for the XSLT.

Related

How does Java Transformer use multiple xslt files

I have one XSLT file including other two xml files to generate html page, like below
<xsl:include href="xsltcache://UtilityTemplates.xml" />
<xsl:include href="xsltcache://eCertSpecificTemplates.xml" />
I do not know how to add multiple xsl sources (three files in this case) to transformer,
Source xslSource = new StreamSource(xslFile);
Transformer trasformToXml=tFactory.newTransformer(xslSource);
You are using a very specialized form of URI in the xsl:include directives, these look as if they were designed to be handled by custom URI dereferencing logic, perhaps an OASIS catalog.
The bog-standard way to do this would be to use relative URIs in the xsl:include (for example <xsl:include href="UtilityTemplates.xsl"/>, to put all three files in the same directory, and then to make sure that the base URI of the main file is known (which it will be if xslFile is a File object).
If there's some special magic to the "xsltcache" URIs then you need to find out what it is. But if you don't want to change the source, you can set a URIResolver on the TransformerFactory. The URIResolver will be called when an xsl:include declaration is encountered, and it can do anything it likes to convert the supplied URI to a Source object containing the included module.

How to parse complex nested xml file in JAVA

i am new to xml parsing not able to decide how to parse this complex xml file in java .
I am able to parse simple xml file but when when it comes to complex xml file i am confused .Not able to read elements of xml using java .
Here is my sample xml file .
<?xml version="1.0"?>
<env:ContentEnvelope xsi:schemaLocation="http://fundamental.schemas.financial.jso.com/Fundamental/2011-07-07/
https://theshare.jso.com/sites/TRM-IA/Content%20Marketplace/Strategic%20Data%20Interfaces/SDI%20Schemas/Schemas/Fundamentals/2015-09-25/FundamentalMaster.xsd"
xmlns:esg="http://fundamental.schemas.financial.jso.com/ESGSupportingInfo/2011-07-07/"
xmlns:md="http://data.schemas.financial.jso.com/metadata/2010-10-10/"
xmlns:cr="http://fundamental.schemas.financial.jso.com/CoraxData/2012-10-25/"
xmlns:ful="http://fundamental.schemas.financial.jso.com/FundamentalLineItem/2011-07-07/"
xmlns:fun="http://fundamental.schemas.financial.jso.com/Fundamental/2011-07-07/"
xmlns:ir="http://fundamental.schemas.financial.jso.com/FinancialInstrumentRelationship/2011-07-07/"
xmlns:fl="http://fundamental.schemas.financial.jso.com/FinancialLineItem/2011-07-07/"
xmlns:pe="http://fundamental.schemas.financial.jso.com/FinancialPeriod/2011-07-07/"
xmlns:seg="http://fundamental.schemas.financial.jso.com/FinancialSegment/2011-07-07/"
xmlns:sr="http://fundamental.schemas.financial.jso.com/FinancialSource/2011-07-07/"
xmlns:sli="http://fundamental.schemas.financial.jso.com/StandardizedLineItem/2011-07-07/"
xmlns:ss="http://fundamental.schemas.financial.jso.com/StandardizedStatement/2011-07-07/"
xmlns:fs="http://fundamental.schemas.financial.jso.com/FinancialStatement/2011-07-07/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:env="http://data.schemas.tfn.jso.com/Envelope/2008-05-01/" minVers="1.0" majVers="3" pubStyle="Message">
<env:Header>
<env:Info>
<env:Id>urn:uuid:069527ab-2c10-48bb-b3d2-206f4e66e5d2</env:Id>
<env:TimeStamp>2016-12-23T10:09:09+00:00</env:TimeStamp>
</env:Info>
<fun:OrgId>20240</fun:OrgId>
<fun:PartitionId>1</fun:PartitionId>
</env:Header>
<env:Body minVers="0.0" majVers="1" contentSet="Fundamental">
<env:ContentItem action="Insert">
<env:Data xsi:type="fun:FundamentalDataItem">
<fun:Fundamental effectiveTo="9999-12-31T00:00:00+00:00" effectiveFrom="2013-06-29T00:55:15.313+00:00" uniqueFuamentalSet="0054341342">
<fun:OrganizationId objectType="Organization" objectTypeId="404510">42565596</fun:OrganizationId>
<fun:PrimaryReportingEntityCode>A4C67</fun:PrimaryReportingEntityCode>
<fun:TotalPrimaryReportingShares>567923000.00000</fun:TotalPrimaryReportingShares>
<fun:LocalLanguageId>505074</fun:LocalLanguageId>
<fun:IndustryGroups>
<fun:IndustryGroup validTo="9999-12-31T00:00:00+00:00" validFrom="1900-01-01T00:00:00+00:00">
<fun:GroupCode>BNK</fun:GroupCode>
<fun:GroupName languageId="505074">Bank</fun:GroupName>
<fun:TaxonomyId>1</fun:TaxonomyId>
<fun:IndustryGroupCodeId>3011649</fun:IndustryGroupCodeId>
</fun:IndustryGroup>
</fun:IndustryGroups>
<fun:GaapCode>CAG</fun:GaapCode>
<fun:ConsolidationBasis>Consolidated</fun:ConsolidationBasis>
<fun:IsFiling>true</fun:IsFiling>
<fun:ConsolidationBasisId>3013598</fun:ConsolidationBasisId>
<fun:GaapCodeId>3011536</fun:GaapCodeId>
<fun:Taxonomies>
<fun:Taxonomy>1</fun:Taxonomy>
</fun:Taxonomies>
<fun:WorldScopeIds>
<fun:WorldScopeId validTo="9999-12-31T00:00:00+00:00" validFrom="2012-03-31T00:00:00+00:00">C12436390</fun:WorldScopeId>
</fun:WorldScopeIds>
</fun:Fundamental>
</env:Data>
</env:ContentItem>
Definitely JAXB will help you here.
Since you are dealing with complex xml files, i would suggest below approach( i agree it's lengthy and manual but shall work fine).
1) Generate xsd schema out of given xml content
2) Create a JAXB project in eclipse and create and empty XSD file and write it with xsd schema generated above
3) To convert .xsd file to pojo Right click on .xsd file and generate JAXB classes
4) Now write a code to un-marshal the data and run it, this should give you a corresponding java class.

Index single Xml-file with Lucene

I'm writing a Java application and want to index an Xml-file with Lucene so I can search for a drug that has a given target. The file size is 400MB and it is filled with over 8000 drug-entries.
<drug type="biotech" created="2005-06-13" updated="2015-11-27">
<drugbank-id primary="true">DB00001</drugbank-id>
<drugbank-id>BIOD00024</drugbank-id>
<drugbank-id>BTD00024</drugbank-id>
<name>Lepirudin</name>
....
<targets>
<target position="1">
<id>BE0000767</id>
<name>Epidermal growth factor receptor</name>
....
</target>
....
</targets>
</drug>
<drug>
....
</drug>
How can I index this file so one drug-entry is one Document?
If someone has some useful links/resources or tips on how to index this Xml please let me know :)
The most flexible strategy is usually to just use SolrJ through a small java application that reads the file and transforms it to a suitable format for indexing in Solr. That way you can easily preprocess certain fields before they're received by Solr.
Another option is to use XSL to transform the XML file into something that Solr understands. This can be used either server-side (as with XSLTUpdateRequestHandler linked) or client-side (transform an XML document into an update request and submit it to the standard request handler).

JAXB and XSLT processor

I am using JAXB and maven-jaxb2-plugin and I am able right now to bind my schemas to Java code successfully.
I also have a .xsl file "annotate_schemas.xsl" that modifies a specific schema adding some additional information.
Finally, on the schema that I want transformed, I added the header:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="annotate_schemas.xsl"?>
...
The problem is that, while the .xsl is correct (if I open my schema file in a browser, the transformation is done flawlessly), JAXB ignores it and binds an untouched version of my schema.
My question is: Does JAXB (and/or its plugin) have an XSLT processor?? Is there a way to tell JAXB to bind the result of the XSLT transformation instead of the original?
Thank you very much
JAXB, like the vast majority of XML-consuming applications, takes no notice of an <?xml-stylesheet?> processing instruction. If you want to transform a document before passing it to JAXB, you need to transform it explicitly, for example by using the JAXP transformation API. (There is an option in JAXP to request transformation according to the value of the xml-stylesheet PI if that's how you want to control it: TransformerFactory.useAssociatedStylesheet()).
You can try something like this:
TransformerFactory transFact = TransformerFactory.newInstance();
Templates displayTemplate = transFact.newTemplates(new StreamSource(new File("your_xsl_file")));
TransformerHandler handler =
((SAXTransformerFactory) transFact).newTransformerHandler(displayTemplate);

Merging template XML with Old Data XMLs

I have to a template XML and a old data XML which may not be having the same structure as the template.
I need to create a new data XML based on the template XML and populate it with values from the old data XML if they are present.
e.g.
Template XML -
<tag1></tag1>
<tag3></tag3>
Old Data XML -
<tag1>value1</tag1>
<tag2>value2</tag2>
New Data XML -
<tag1>value1</tag1>
<tag3></tag3>
I need to achieve this using Java.
Can this be done using Java XSL Transformers? Or do I need some External APIs?
There is an interesting thread here that talks about the same thing.
XSLT: A simple way to merge xml files
Hope this will help you.

Categories