How to change the xml properties from default properties? - java

The above screen capture shows the expected output and actual output, red color indicates that it differs from the actual output that is shown in green color.
To create xml document I have used the marshall concept.Java code used to create xml document are given below.
import com.ehf.bean.Invoice;
import com.sap._0050089212_one_off.ypt74nkey_.StandardFaultMessage;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.xml.sax.SAXException;
public class Ehf {
public static void main(String[] args) throws ParserConfigurationException,
TransformerException, SAXException, IOException, StandardFaultMessage,
com.sap.xi.a1s.global.StandardFaultMessage, JAXBException {
JAXBContext contextObj = JAXBContext.newInstance(Invoice.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Invoice invoice = new Invoice();
invoice.setCustomizationID("dsf");
invoice.setInvoiceTypeCode(0);
marshallerObj.marshal(invoice, new FileOutputStream("question.xml"));
}
}
Note: Invoice class is generated using xsd, through xjc command.
How can resolve this problem?

#javax.xml.bind.annotation.XmlSchema(
namespace = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
xmlns ={#XmlNs(prefix="cac", namespaceURI="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"),
#XmlNs(prefix="cbc", namespaceURI="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"),
#XmlNs(prefix="", namespaceURI="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2")
})
The above code is working for me as expected, this code should be write in package-info.java

Related

JAXB : Unmarshal object with 2 name spaces results in a null value

I am getting null value when i try to unmarshal XML file ,
I have created package-info.java class with 2 name spaces as explained below.
Please suggest how to fix this issue
1. My XML file looks like below :It has 2 name spaces
<?xml version="1.0" encoding="UTF-8"?>
<saleResponse xmlns="http://tripos.vantiv.com/2014/09/TriPos.Api" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<_type>saleResponse</_type>
</saleResponse>
2. i have declared package-info.java like below
#XmlSchema(
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
#XmlNs(prefix="", namespaceURI="http://tripos.vantiv.com/2014/09/TriPos.Api"),
#XmlNs(prefix="i", namespaceURI="http://www.w3.org/2001/XMLSchema-instance")
}
)
#XmlAccessorType(XmlAccessType.FIELD)
package test1;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.*;
3. SaleResponse class is :
package test1;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "saleResponse", namespace = "http://tripos.vantiv.com/2014/09/TriPos.Api")
public class SaleResponse {
#XmlElement(name = "_type")
public String _type;
}
4. I am getting null value when i try to unmarshal XML file
package test1;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class JAXBExample {
public static void main(String[] args) {
try {
File file = new File("C:\\Ravi\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(SaleResponse.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
SaleResponse saleResponse = (SaleResponse) jaxbUnmarshaller.unmarshal(file);
System.out.println(saleResponse._type);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
**I am getting null value when i try to unmarshal XML file ,
I have created package-info.java class with 2 name spaces as explained below.
Please suggest how to fix this issue**
You have to add the default namespace="http://tripos.vantiv.com/2014/09/TriPos.Api" attribute into your package-info.java and you can remove the empty prefix one also: #XmlNs(prefix="", namespaceURI="http://tripos.vantiv.com/2014/09/TriPos.Api").
It should work as your expected, output is: saleResponse
package-info.java
#XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace="http://tripos.vantiv.com/2014/09/TriPos.Api", xmlns = {
#XmlNs(prefix = "i", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance") })
#XmlAccessorType(XmlAccessType.FIELD)
package test1;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.*;
For more information: https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlSchema.html

Maintain whitespace in JAXB with xs:any and mixed content

I have a schema with an xs:any element. This element may contain other elements that have mixed content. I'm trying to use JAXB to unmarshall it into Java objects (with the 'any' as an Element).
From the schema:
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
In general, this works. But when handling elements with mixed content, whitespace between nested nodes is lost.
test.xml:
<a><foo><b>Hello</b> <i>World</i></foo></a>
Unmarshalling like this:
JAXBContext jc = JAXBContext.newInstance(A.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
InputStream inputStream = this.getClass().getResourceAsStream("/data/test.xml");
A a = (A) unmarshaller.unmarshal(inputStream);
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(a, System.out);
Results in this:
<a><foo><b>Hello</b><i>World</i></foo></a>
I lose the space between the child tags of the <foo> element. I'm certain that it's the unmarshal step that takes the whitespace out here, but I do need it to survive the round trip.
Note that it's only whitespace-only text content that's removed. This works as desired:
<a><foo><b>Hello</b> to you <i>World</i></foo></a>
I tried adding xml:space="preserve" (see, for example, JAXB: How to keep consecutive spaces as they are in source XML during unmarshalling), but that has no effect on whitespace between elements. I've tried with processContents set to each of strict, lax, and skip, none of which helped.
After facing a similar issue I could come up with the following solution (to this specific scenario, as for some other complex XML structures it doesn't work perfectly).
package com.stackoverflow.answers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.transform.stream.StreamSource;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.w3c.dom.Element;
public class XmlAnyElementWithWhiteSpacesTest {
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "a")
private static class A {
#XmlAnyElement
#XmlMixed
private List<Element> elements;
}
private static final String SAMPLE = "<a><foo><b>Hello</b> <i>World</i></foo></a>";
#Test
public void shouldParseAndSerializeKeepingWhiteSpaceElements() throws JAXBException {
// given
JAXBContext jc = JAXBContext.newInstance(A.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
InputStream inputStream = new ByteArrayInputStream(SAMPLE.getBytes(StandardCharsets.UTF_8));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
// when
JAXBElement<A> a = unmarshaller.unmarshal(new StreamSource(inputStream), A.class);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
marshaller.marshal(a.getValue(), outputStream);
String actual = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
// then
assertEquals(SAMPLE, actual);
}
}
The key points here are:
Usage of #XmlMixed annotation
Usage of StreamSource
You can use either List<Object> or List<Element> for your "XML any content" property.

Line number of xinclude while unmarshalling using jaxb

I found this question on SO. I shows how to get the line numbers of individual xml elements while unmarshalling with JAXB. I extended this example being able to use xinclude. Unfortunately, I'm not able to get the line number of the xinclude.
So, how do I get the line number of the actual xinclude statement? Here is the extended example:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class Demo {
public static void main(String[] args) throws JAXBException, SAXException,
ParserConfigurationException, FileNotFoundException {
JAXBContext jc = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setXIncludeAware(true);
spf.setNamespaceAware(true);
spf.setValidating(true);
File file = new File("src/person.xml");
XMLReader xr = spf.newSAXParser().getXMLReader();
xr.setEntityResolver(new EntityResolver() {
#Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
System.out.println(publicId + " -> " + systemId);
return null;
}
});
SAXSource source = new SAXSource(xr, new InputSource(
new FileInputStream(file)));
Person person = (Person) unmarshaller.unmarshal(source);
System.out.println("Person: " + person.locator.getLineNumber());
System.out.println("Address: "
+ person.address.locator.getLineNumber());
}
}
The EntityResolver listener tells me that there is an xinclude statement, but I don't know on which line number.
person.xml
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:xi="http://www.w3.org/2001/XInclude">
<name>Jane Doe</name>
<xi:include href="./src/address.xml" />
</person>
address.xml
<?xml version="1.0" encoding="UTF-8"?>
<address>1 A Street</address>
I didn't mention the Person and Address class, so this questions stays short and compact :) I also marked every Locator field with #XmlTransient. Thank you!

Reading XML online and Storing It (Using Java)

I found and followed an example from Stackoverflow (http://stackoverflow.com/questions/2310139/how-to-read-xml-response-from-a-url-in-java) of how to read an XML file from a URL (as you can see in my code pasted below). My only trouble is that now that I got the program to read the XML, how do I get it to store it? For example, could I make it save the information to a XML file built into the project (this would be the best solution for me, if it's possible)? Such as, take for example, I have a blank XML file built into the project. The program runs, reads the XML code off of the URL, and stores it all into the pre-built blank XML file. Could I do this?
If I sound confusing or un-clear about anything, just ask me to clarify what I'm looking for.
And here is my code, if you'd like to look at what I have so far:
package xml.parsing.example;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class XmlParser {
public static void main (String[] args) throws IOException, ParserConfigurationException, SAXException, TransformerException {
URL url = new URL("http://totheriver.com/learn/xml/code/employees.xml");
URLConnection conn = url.openConnection();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(conn.getInputStream());
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer xform = tfactory.newTransformer();
// that’s the default xform; use a stylesheet to get a real one
xform.transform(new DOMSource(doc), new StreamResult(System.out));
}
}
Very simply:
File myOutput = new File("c:\\myDirectory\\myOutput.xml");
xform.transform(new DOMSource(doc), new StreamResult(myOutput));
This page has some great examples of how to serialize the DOM object to a neatly formatted XML file.

Parsing XML document YQL query in Java

I want to use the information from XML response produced by using YQL for stock historical data, like this link
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.historicaldata%20where%20symbol%20in%20(%22MSFT%22)%20and%20startDate%3D%222011-2-12%22%20and%20endDate%3D%222011-2-15%22%0A%09%09&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env
And store it into a stock objects array. I am new to Java and I have no knowledge of its XML api's. I dont know what is the simple way to do it. Can someone suggest me a good solution. Thanks.
You could do the following using a JAXB (JSR-222) implementation:
Metro JAXB (the reference implementation included in Java SE 6)
EclipseLink JAXB (MOXy), I'm the tech lead
Apache JaxMe
etc.
Demo
import java.io.InputStream;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Stock.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
URL url = new URL("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.historicaldata%20where%20symbol%20in%20(%22MSFT%22)%20and%20startDate%3D%222011-2-12%22%20and%20endDate%3D%222011-2-15%22%0A%09%09&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env");
InputStream xmlStream = url.openStream();
Stock stock = (Stock) unmarshaller.unmarshal(xmlStream);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(stock, System.out);
}
}
Stock
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="query")
#XmlAccessorType(XmlAccessType.FIELD)
public class Stock {
#XmlElementWrapper(name="results")
#XmlElement(name="quote")
private List<Quote> quotes;
}
Quote
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
#XmlAccessorType(XmlAccessType.FIELD)
public class Quote {
#XmlElement(name="Date")
#XmlSchemaType(name="date")
private Date date;
#XmlElement(name="Open")
private double open;
#XmlElement(name="High")
private double high;
#XmlElement(name="Low")
private double low;
#XmlElement(name="Close")
private double close;
#XmlElement(name="Volume")
private long volume;
#XmlElement(name="Adj_Close")
private double adjClose;
}

Categories