Java API for XML Schema manipulation - java

I am familiar with JAXB, JAXP and DOM. I know JAXB provides java2xml and xml2java generation(and validation against XML Schema(XSD)). What I want is convenient way to produce XML schema programmatically from scratch. I do not want to produce XSD from java classes. I want to have an object representing the schema itself. For example:
XMLSchemaFactory factory = XMLSchemaFactory.newInstance();
XMLSchema schema = factory.newSchema();
schema.setTargetNameSpace("http://www.example.com");
...
schema.addComplexType(complexTypeElement);
...
schema.addElement(name, type);
...
schema.export(new File("mySchema.xsd"));
I know XML schema is itself XML, so I can use Document, Element, Node and other classes/interfaces from org.w3c.dom, but I wonder is there something more convenient ?
Why I want this - I have some IDL, which I have to translate to WSDL. I have lexer/parser for the IDL and I have convenient representation of it as java objects. Now I want to produce the WSDL using this objects => a lot of XML schemas have to be generated !

From my point use WSDL4J it would be pretty easier for your xml manipulations.
Refer this pdf for more details.
http://wsdl4j.sourceforge.net/downloads/JSR110_proposed_final_draft.pdf

Related

Writing an XML SOAP message in Java

I have the following method that accepts xml and I do some data feeding with the content.
I am supposed to return a SOAP message as well, something along these lines:
<ow-e:Envelope revision='2.0' xmlns:ow-e='http://www.url.com/test-envelope'>
<ow-e:Header>
<ow-e:Properties>
<ow-e:SentAt>2004-12-14T13:54:36</ow-e:SentAt>
<ow-e:Topic>SOME_STRING</ow-e:Topic>
</ow-e:Properties>
</ow-e:Header>
</ow-e:Envelope>
So right now what I am doing is the following:
String some_string = "qwe";
String response = "";
response = "<ow-e:Envelope revision='2.0' xmlns:ow-e='http://www.url.com/test-envelope'><ow-e:Header><ow-e:Properties><ow-e:SentAt>2004-12-14T13:54:36</ow-e:SentAt><ow-e:Topic>" + some_string + "</ow-e:Topic></ow-e:Properties></ow-e:Header></ow-e:Envelope>";
return response;
Which is absolutely terrible. Any idea how I can actually make it more bearable? Using a framework is not an option at the moment.
This is the first time I am dealing with SOAP messages/responses and it feels like hell coming from REST. I probably need to create some kind of hierarchy to populate the values correctly, but I am not sure how it can be done just by using Java without any frameworks.
You mentioned using frameworks is not an option, but something more lightweight may be available in your platform:
JAXB. JAXB allows you to map Java classes to XML representations using annotations. It's far better than doing marshaling and unmarshaling by hand or by concatenating or parsing strings. With properly structured and annotated POJOs, JAXB can handle things for you. You might even be able to cheat and use xjc with your WSDL file to create annotated classes with the -wsdl option (experimental though).
SAAJ. Bluntly put, SAAJ is just like a specific builder and parser for SOAP messages. It will handle the structure and namespaces for you. Speaking of which...
... the example you are showing isn't really valid SOAP message. SOAP is a protocol. You need to properly format it and use the right namespaces otherwise you are just returning some XML messages that look like SOAP, but aren't.

How to create multiple xml request by only changing one field?

I need help to find the approach of how to create xml multiple times while I will be changing only two fields everytime and rest of the fields would be same as now. Please tell me the way to do it in java?
This is the sample xml below:
I would be changing the value of <Id> and <Originator>
<TransactionBlk>
<Id>NIK</Id>
<CorrelationId />
<Originator>NIK</Originator>
<Service>GetIns</Service>
<VersionNbr>1</VersionNbr>
<VersionNbrMin>0</VersionNbrMin>
<MsgNm>Req</MsgNm>
<MsgFormatCd>XML</MsgFormatCd>
</TransactionBlk>
You can crate one class contain all this parameter as class variable, create getter and setter method. Create object of class set value by using setter method.
You can use JAXB API's class to convert your java object into XML format.
The JAXBContext class provides the client's entry point to the JAXB API.
It provides an abstraction for managing the XML/Java binding information
necessary to implement the JAXB binding framework operations: unmarshal,
marshal and validate.
Here is Doc reference for convert your Java object into XML.
Here are tutorial for same Tutorial Link
Sample Code :
#XmlRootElement(name="TransactionBlk_REQ",namespace="http://TransactionBlk.com")
#XmlAccessorType(XmlAccessType.FIELD)
public class TransactionBlk
{
#XmlElement(name = "Id")
private String id;
#XmlElement(name = "Originator")
private String Originator;
//Your getter and setter method.
}
TransactionBlk bean = new TransactionBlk();
//Set your parameter value here
StringWriter responseWriter = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(TransactionBlk.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(bean, responseWriter);
String xmlStr = responseWriter!=null?responseWriter.toString():null;
You can use XSLT to transform XML.
If all you're doing is printing a "boilerplate" document with changes in those two values, a, you could use the DPH (Desperate Perl Hacker) approach: simply assemble it as text, pausing to print the values at the appropriate places. To be safe, you should pre-scan the values to make sure they don't contain the <, >, or & characters and escape those if you find them.
For something more complex, or if you want to start learning how to do it "properly", look at the standard XML APIs for Java: DOM (the Document Object Model, an in-memory tree model of a document), SAX (an event-stream view of a document), and JAXP (tools to take an XML document and parse it into DOM or SAX so you can read it, and to take DOM or SAX and write those out as XML syntax). JAXP also provides standard APIs for invoking XPath to search a document and XSLT to apply a stylesheet to a document, so taken together these cover a huge percentage of the basic operations on XML.
You might want to look at some tutorials on using Java to manipulate XML. I'm certainly biased, not least because they published one of my articles, but in my experience IBM's DeveloperWorks website (https://www.ibm.com/developerworks/xml/) has had better-than-average material for learning about XML and other standards.

JAX-WS and Enunciate - How to change Enunciate's default XSD naming convention

I'm using Enunciate to generate a SOAP endpoint for a Wicket web application I am working on and I have a couple of questions that I haven't figured out the solution to yet.
1 How do I change the name of the xsd files? I've looked through the FAQ and it tells me to do something similar to this:
<xml>
<schema namespace="http://api.example.com/data" file="data.xsd"/>
</xml>
However, I haven't quite figured out how to set the targetNamespace for my data objects. I've done this for my service via #WebService ( targetNamespace="blah" ), but how do I annotate my data objects to let Enunciate know which namespace they should belong to?
2 Enunciate generates my XSDs just fine, but I don't particularily like the element names it uses. I have a ServiceRequest and ServiceResponse object. The ServiceRequest object has a List of User objects. The ServiceResponse has a list of Group objects. Enunciate suggests that every "User" object within the ServiceRequest should be using the tag "<users>". I feel that it would make more sense to use the singular form, "<user>" since the tag does in fact only contain a single user. Is it possible to change this behaviour, and if so, how?
Thanks in advance.
So just to be clear, with the exception of the question about naming your schema files, your questions are really more about JAXB than they are about Enunciate. JAXB is the spec that defines how your Java objects are (de)serialized to/from XML and Enunciate conforms to that spec.
Anyway, the easiest way to apply a namespace to your Java objects is with a package-info.java file in the package of your Java classes. Annotate your package with #XmlSchema and set the namespace to be the value you want.
Customizing how your accessors are serialized to/from XML can be done with the #XmlElement annotation, e.g.:
public class MyClass {
...
#XmlElement (name="user")
List<User> users;
...
}
Here are the JAXB javadocs
https://jaxb.dev.java.net/nonav/2.1.9/docs/api/
Or google for a good JAXB tutorial.

How should I use Stax2 Validation API against a W3 Schema

I am using com.ctc.wstx.stax.WstxOutputFactory to generate XML.
I am running wstx-asl-3.2.4
I need to start validating the generated XML against a W3 Schema.
When I create an instance of org.codehaus.stax2.validation.XMLValidationSchemaFactory like this
private final static XMLValidationSchemaFactory xsdFact=
XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
I get the error
javax.xml.stream.FactoryConfigurationError: No XMLValidationSchemaFactory implementation class specified or accessible (via system property 'org.codehaus.stax2.validation.XMLValidationSchemaFactory.w3c', or service definition under 'META-INF/services/org.codehaus.stax2.validation.XMLValidationSchemaFactory.w3c')
at org.codehaus.stax2.validation.XMLValidationSchemaFactory.newInstance(XMLValidationSchemaFactory.java:208)
at org.codehaus.stax2.validation.XMLValidationSchemaFactory.newInstance(XMLValidationSchemaFactory.java:98)
I can see that woodstox is bundled with a DTD parser only.
I found this article
which contains the unhelpful instruction
Get an instance of XMLValidationSchemaFactory that knows how to parse schemas of the type you need (RelaxNG == rng for this example).
I have been looking at the Sun Multi-Schema XML Validator which is supposed to contain the bits necessary to bolt on to the XMLSchemaValidation factory.
It looks like I might be able to use com.sun.msv.reader.xmlschema.XMLSchemaReader
to write my own instance of XMLValidationSchemaFactory and get it to work this way.
My question is; do I really have to do this, or is there a pre-existing w3c schema factory that I have failed to find?
Perhaps it would be simpler just to validate the XML after I have generated it.
What are the views on this ?
I've upgraded to Woodstox 4.0.8, W3CSchemaFactory comes bundled and its all good.

Easiest parser in Java for xml to generate code for newcomer in xml

Guys I'm new to xml in Java.
I have the following task. I need to parse some xml files (specificallyh xcb-proto [X11]) to generate the equivalent request protocol in java. There is already a well defined xsd and the respective xml for the protocol. What is the best and easiest approach/parser to solve this?
Example of existant xml content:
<request name="SetScreenSaver" opcode="107">
<pad bytes="1" />
<field type="INT16" name="timeout" />
<field type="INT16" name="interval" />
<field type="CARD8" name="prefer_blanking" enum="Blanking" />
<field type="CARD8" name="allow_exposures" enum="Exposures" />
</request>
This will generate a Java DOM (?) Object. And them with this I need to generate the given code in Java. For this case is:
Desired output:
public void setScreenSaver(int timeout, int interval, int preferBlanking, int allowExposures) {
RequestOutputStream o = outputStream;
synchronized (o) {
o.beginRequest(107, 0, 1); // Major Opcode , Minor Opcode, ReqLength
o.writeInt16(timeout);
o.writeInt16(interval);
o.writeInt8(preferBlanking);
o.writeInt8(allowExposures);
o.send();
}
}
It seems that XSOM is the one that gives the easier approach...
PS: I have never manipulated xml files in Java :3
You should look into JAXB. It comes with a utility that will generate all your Java code using the .XSD file to determine the structure.
Even with an XSD parser, this is never going to be an easy task, especially if the schema uses some of the more difficult aspects of the XSD language.
If this is a once-off task and the XSDs are not huge, then you are probably better of just writing the Java code by hand.
EDIT
I can think of one roundabout approach using Eclipse / EMF that might simplify things:
Use the EMF tooling to create a EMF ECore model from the XSD. This gives you an in-memory "object model" analogous to simple UML.
Using EMF infrastructure (e.g. JET), create a custom generator that traverses the ECore model and generates your target code.
The XSD to ECore also gives you (for free) generated classes for representing your XML in memory, editing it in a tree editor and reading/writing the XML. Associated technologies deal with persistence in a database, validation, model-to-model transformation, and other things.

Categories