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.
Related
I have a list of objects which needs to be converted to JSON. I also have a JSON schema corresponding to which the objects should be placed in the JSON to be created. How can I achieve this? I cannot seem to find any references on the internet. Is this possible? Any help would be much appreciated.
If it's JavaScript, you can do it using Ajv and custom keywords that would generate the object you need as a side-effect of validation process.
Most likely you would have to define template that will be validated and the data that needs to be embedded in this template will be passed as a context into validation function:
var validate = ajv.compile(schema);
var context = { data: { /* ... */ } };
validate.call(context, template);
console.log(template); // template with inserted data
There is no Java technology that that uses a json schema to influence serialization that I am aware of. If you use a library such as Jackson to serialize, it's up to you to use the available customization mechanisms to make any changes to the defaults needed to conform to the schema.
I have an application that uses JAXB (Moxy) and Saxon for running XPath expressions. Everything works as expected, but Saxon's DocumentBuilder emits this warning:
XML Parser does not recognize the feature http://xml.org/sax/features/validation
Code:
Processor proc = new Processor(false);
DocumentBuilder builder = proc.newDocumentBuilder();
XdmNode doc = builder.build(new JAXBSource(jaxbContext, jaxbObject));//The warning occurs here
...
I think what's going on is JAXB is using a StaX parser and Saxon uses SAX. So when Saxon attempts to set the above property on the StaX parser, it fails.
Is there a way to prevent Saxon from setting that property when building the document or, at the very least, suppress that warning? I've tried setting a bunch of different properties on the Processor, but none of them worked. I don't need validation anyway since the document has already been validated and read into a JAXB object.
EDIT: I've been trying to override the errorListener on the Processor, DocumentBuilder, and the JAXBSource, but that message is not going through any of them.
I'll look into this a bit more closely, but the first thing to say is that JAXBSource extends SAXSource, and Saxon treats it exactly like it treats any other SAXSource. The warning in the JAXB documentation "Thus in general applications are strongly discouraged from accessing methods defined on SAXSource" is vacuous - applications (like Saxon) when they are defined to accept an object of class X, don't in general take any notice of advice given in the specifications of a subclass of X that they have never heard of.
The status of the property "http://xml.org/sax/features/validation" is a little unclear. IIRC the SAX specifications don't say that every XMLReader must recognize this property, but they do define it as the only way of requesting DTD expansion, and an XSLT processor needs DTD expansion to take place; if the XMLReader doesn't do DTD expansion then the transformation may fail in unpredictable ways, so a warning is justified.
The cleanest way of suppressing the warning is probably to supply an XMLReader that does recognise this property, and delegate from there to an XMLReader that doesn't recognise it.
private class SaxonLogger extends StandardLogger {
#Override
public void warning(String message) {
if(!message.contains("http://xml.org/sax/features/validation")) {
System.err.println(message);
}
}
}
...
proc.getUnderlyingConfiguration().setLogger(logger);
This will at least suppress those pesky messages. However, I would still like to find a better solution.
I am getting a XML response and it keeps on changing very frequently (nodes keep on increasing or reducing). After each updation in response xml my code breaks as my mapped Java class does not have all fileds.
Is there any way to avoid my code breaking if any changes occurs in response XML.
Any help will be appreciated.
Thanks.
Use JAXB.unmarshal() to simply create Java objects from XML.
By default it is very liberal.
Quoting from the javadoc:
In addition, the unmarshal methods have the following characteristic:
Schema validation is not performed on the input XML. The processing will try to continue even if there are errors in the XML, as much as possible. Only as the last resort, this method fails with DataBindingException.
So what JAXB.unmarshal() does is it tries to "transfer" as much data from XML to Java as possible, and it doesn't care if there is no Java field for an XML element or attribute, and it also doesn't care if there is a Java field for which there is no XML element or attribute.
Example
Let's try to unmarshal the following XML to an instance of java.awt.Point:
<p hi="Yo">
<y>123</y>
<peach>weor</peach>
</p>
The Java code:
String s = "<p hi=\"Yo\"><y>123</y><peach>weor</peach></p>";
Point p = JAXB.unmarshal(new StringReader(s), Point.class);
System.out.println(p); // Prints "java.awt.Point[x=0,y=123]"
We told JAXB.unmarshal() to parse a java.awt.Point instance. The input XML contains an element <y> which can be matched with Point.y so an int was parsed and set to Point.y. No XML data was found for Point.x so it was not touched. There were no match for the attribute hi and the XML element <peach>, so they were simply not used for anything.
We got absolutely no Exception here, and the most that was possible was parsed and transferred from XML to Java.
To cope with unknown fields, you can add a List<Object> property annotated #XmlAnyElement(lax=true)
#XmlAnyElement(lax = true)
private List<Object> anything;
Any elements in the input that do not correspond to explicit properties of the class will be swept up into this list. If the element is known to the JAXBContext you'll get the unmarshalled form (the #XmlRootElement annotated class or a JAXBElement<Foo>), if the element is not known to the context you'll get an org.w3c.dom.Element.
Full details in Blaise's blog.
For nodes that get removed you should be fine as long as you use types that can be null (Integer rather than int, Boolean rather than boolean, etc).
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
It seems the standard approach for deserializing JAXB XML is to specify the package name when creating the context. Then, JAXB looks up the class based on the root element:
JAXBContext jc = JAXBContext.newInstance("com.foo");
Unmarshaller u = jc.createUnmarshaller();
Object o = u.unmarshal(new StringReader("<?xml version="1.0" encoding="UTF-8" standalone="yes"?><MyJaxb>..."));
I'm looking for a more flexible approach where I don't have to specify the package name and could still deserialize any object. This would be as simple as JAXB storing the package in the XML, but I can't seem to find out how to do this. I can write the code to do it myself but that would be unpleasant. It would like JAXB to do it, if possible. BTW, I am not using schemas, just Annotations and marshal/unmarshal. Any ideas?
Actually you can not deserialize "any" object with pure JAXB. You have to specify either packages (where ObjectFactory.class will be sought) or list of classes like JAXBContext.newInstance(Class1.class, Class2.class, Class3.class); That's how jaxb works, it's a part of agreement.
If your tasks are wider that that, e.g. building java classes from arbitrary xml data structure - it's also possible, but you have to be a bit more concrete - what do you mean under "more flexible approach".
You should be able to add more than one package when you get the instance of the jaxbcontext object. You can add as many packages as you want like below.
JAXBContext jc = JAXBContext.newInstance("com.foo.package1:com.foo.package2" );
however, I am not sure how you are gonna use it if you deserialize it into an Object instance?
Are you not gonna use what you have just deserialized?
Also Unmarshaller is not a thread safe class if your application is a multithreaded one.