getting data from xml to java - java

How could I get the data from a xml, which is generated with php, in java.
I need the data to display it in a listview in my android app.
The phpcode take the data form the mysqlquery and fetch the array in the variabel xml and put it over echo out. The data for the mysqlquery are from the android app over POST.
phpcode:
//MySQL zugangsdaten
$server = "server";
$datenbank = "database";
$username = "username";
$passwort = "password";
//Verbindung zur MySqldatenbank herstellen
$link = mysql_connect($server, $username, $passwort);
if (!$link) die(mysql_error());
//Datenbank auswählen
$db = mysql_select_db($datenbank, $link);
//<---- End Login ---->
$_linie = htmlspecialchars(mysql_real_escape_string($_POST["linie"]), ENT_COMPAT);
$_richtung = htmlspecialchars(mysql_real_escape_string($_POST["richtung"]), ENT_COMPAT);
$sql_befehl = "SELECT * From Kontrolleure where linie = '$_linie' AND richtung = '$_richtung'";
$query = mysql_query($sql_befehl, $link);
if(mysql_error())
{
die(mysql_error());
}
while($result = mysql_fetch_array($query, MYSQL_ASSOC))
{
$count = $count + 1;
$xml = $xml."<Konduktor>";
$xml = $xml."<id>".$result['id']."</id>";
$xml = $xml."<linie>".$result['linie']."</linie>";
$xml = $xml."<endstation>".$result['richtung']."</endstation>";
$xml = $xml."<station>".$result['station']."</station>";
$xml = $xml."<zeit>".$result['zeit']."</zeit>";
$xml = $xml."</Konduktor>";
}
echo "<Konduktors count=\"$count\">";
echo $xml;
echo "</Konduktors>";
the xml response looks like this:
<Konduktors count="3">
<Konduktor>
<id>29</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Brugg AG</station>
<zeit>17:36:34</zeit>
</Konduktor>
<Konduktor>
<id>30</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Lupfig</station>
<zeit>17:37:12</zeit>
</Konduktor>
<Konduktor>
<id>32</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Birr</station>
<zeit>16:23:30</zeit>
</Konduktor>
</Konduktors>
Thank you!

There are xml parsing tools for this kind of thing. At my work we use XMLBeans:
http://xmlbeans.apache.org/
I found using it to be fairly straightforward, and am kind of a rank amateur at this kind of stuff.

JAXB would handle that easily:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
public class JaxbExample {
public static void main(String[] args) throws JAXBException {
String xml =
"<Konduktors count=\"3\">\n" +
" <Konduktor>\n" +
" <id>29</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Brugg AG</station>\n" +
" <zeit>17:36:34</zeit>\n" +
" </Konduktor>\n" +
" <Konduktor>\n" +
" <id>30</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Lupfig</station>\n" +
" <zeit>17:37:12</zeit>\n" +
" </Konduktor>\n" +
" <Konduktor>\n" +
" <id>32</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Birr</station>\n" +
" <zeit>16:23:30</zeit>\n" +
" </Konduktor>\n" +
"</Konduktors>";
Object object = JAXBContext.newInstance(Konduktors.class).createUnmarshaller().unmarshal(new StringReader(xml));
System.out.println(object);
}
#XmlRootElement(name = "Konduktors")
static class Konduktors {
private List<Konductor> konductors = new ArrayList<Konductor>();
#XmlElement(name = "Konduktor")
public List<Konductor> getKonductors() {
return konductors;
}
public void setKonductors(List<Konductor> konductors) {
this.konductors = konductors;
}
#Override
public String toString() {
return "Konductors{" +
"konductors=" + konductors +
'}';
}
}
static class Konductor {
private int id;
private String linie;
private String endstation;
private String zeit;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLinie() {
return linie;
}
public void setLinie(String linie) {
this.linie = linie;
}
public String getEndstation() {
return endstation;
}
public void setEndstation(String endstation) {
this.endstation = endstation;
}
public String getZeit() {
return zeit;
}
public void setZeit(String zeit) {
this.zeit = zeit;
}
#Override
public String toString() {
return "Konductor{" +
"id=" + id +
", linie='" + linie + '\'' +
", endstation='" + endstation + '\'' +
", zeit='" + zeit + '\'' +
'}';
}
}
}
Other options include XStream or XMLBeans for higher-level abstractions and dom4j or JDOM for lower-level ones--you have to do more work with these but have a lot more flexibility.

Related

Convert JSON to POJO having Json property as jsonObject having diffrent property

I have new requirement, I am creating REST API which has dynamic request (actions) and I want to convert that JSON request to POJO, I know how to convert JSON to POJO where key's are same, but not sure what to do when there are different content on objects.
My Json is as follow.
{
"name":"Workflow",
"actions": [
{
"name": "EDIT_PROPERTY",
"payload": {
"name": "city",
"value": "Pune"
}
},
{
"name":"SEND_EMAIL",
"payload":{
"from":"no-reply#yaho.com",
"to":"alpesh#yahoo.com",
"subject":"Try email",
"body":"content"
}
},
{
"name":"CREATE_TASK",
"payload":{
"user":1,
"type":"call",
"status":"open",
"note":"This is note content"
}
}
]
}
As you can see actions are set of Objects which has name and payload, now payload has different fields, I have predefined names. and each payload under action has predefined keys as you see.
I want to convert this to POJO something like
class Workflow{
String name;
Set<Action> actions;
}
class Action {
String name;
//What to add as payload
}
Thanks
Alpesh
This is what you can do :
JSON to POJO model :
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Event {
public String name;
public List<Action> actions;
#Data
public static class Action {
public String name;
Map<String, Object> payload;
}
}
public class TestJson {
private static String json = "{\n" +
" \"name\":\"Workflow\",\n" +
" \"actions\": [\n" +
" {\n" +
" \"name\": \"EDIT_PROPERTY\",\n" +
" \"payload\": {\n" +
" \"name\": \"city\",\n" +
" \"value\": \"Pune\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"name\":\"SEND_EMAIL\",\n" +
" \"payload\":{\n" +
" \"from\":\"no-reply#yaho.com\",\n" +
" \"to\":\"alpesh#yahoo.com\",\n" +
" \"subject\":\"Try email\",\n" +
" \"body\":\"content\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"name\":\"CREATE_TASK\",\n" +
" \"payload\":{\n" +
" \"user\":1,\n" +
" \"type\":\"call\",\n" +
" \"status\":\"open\",\n" +
" \"note\":\"This is note content\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
#SneakyThrows
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Event event = objectMapper.readValue(json, Event.class);
System.out.println(event);
}
}
When debugging, you'll notice that our objects have been filled accordingly:
Well, generally, I prefer any solution that does not involve Component Annotations. This is my own personal preference because eliminating constructors and method parameters is usually a giant headache. This is based on 1999 - 2006 Java Programming experience. If you have a need to dynamically generate classes and constructors or getters, then you may easily ignore or delete this answer. For me, JSON Parsing is practice right now.
In this posted answer, I have used the older Java JSON Library whose JavaDoc may be viewed here: javax.json.*. Here is my solution. It requires / expects that you write:
Your own toString() methods for your JSON Data Classes
Your own retrieve operations
The following code has output, and that is included at the end of this post. Usually I include a lot of Code Documentation. However, when the code is strictly parsing data, the code itself is usually so legible that more comments would clutter the retrieve and the toString() operations, so I have left them as is.
import java.util.*;
import javax.json.*;
import java.io.*;
public class Messages
{
public abstract static class Action
{
public final String name;
public Action(String name) { this.name=name; }
}
public static class EditProperty extends Action
{
public final String propName, propValue;
public EditProperty(String name, String value)
{ super("EDIT_PROPERTY"); this.propName=name; this.propValue=value; }
public String toString()
{
return
"Action: " + name + '\n' +
"Name: " + propName + '\n' +
"Value: " + propValue + '\n';
}
}
public static class SendEmail extends Action
{
public final String from, to, subject, body;
public SendEmail(String from, String to, String subject, String body)
{ super("SEND_EMAIL"); this.from=from; this.to=to; this.subject=subject; this.body=body; }
public String toString()
{
return
"Action: " + name + '\n' +
"From: " + from + '\n' +
"To: " + to + '\n' +
"Subject: " + subject + '\n' +
"Body: " + body + '\n';
}
}
public static class CreateTask extends Action
{
public final int user;
public final String type, status, note;
public CreateTask(int user, String type, String status, String note)
{ super("CREATE_TASK"); this.user=user; this.type=type; this.status=status; this.note=note; }
public String toString()
{
return
"Action: " + name + '\n' +
"User: " + user + '\n' +
"Type: " + type + '\n' +
"Status: " + status + '\n' +
"Note: " + note + '\n';
}
}
public static void main(String[] argv) throws IOException
{
Vector<Action> actions = new Vector<>();
Reader r = new FileReader("in.json");
JsonArray actionList = Json
.createReader(r)
.readObject()
.getJsonArray("actions");
for (JsonObject actionObj : actionList.getValuesAs(JsonObject.class))
{
JsonObject payload = actionObj.getJsonObject("payload");
Action action = null;
switch (actionObj.getString("name"))
{
case "EDIT_PROPERTY" : action = new EditProperty(
payload.getString("name"),
payload.getString("value")
); break;
case "SEND_EMAIL" : action = new SendEmail(
payload.getString("from"),
payload.getString("to"),
payload.getString("subject"),
payload.getString("body")
); break;
case "CREATE_TASK" : action = new CreateTask(
payload.getInt("user"),
payload.getString("type"),
payload.getString("status"),
payload.getString("note")
); break;
}
actions.add(action);
}
for (Action action : actions) System.out.println(action);
}
}
The class and inner-classes above would produce this output when invoked at the command line:
#cloudshell:~$ java Messages
Action: EDIT_PROPERTY
Name: city
Value: Pune
Action: SEND_EMAIL
From: no-reply#yaho.com
To: alpesh#yahoo.com
Subject: Try email
Body: content
Action: CREATE_TASK
User: 1
Type: call
Status: open
Note: This is note content
The JSON you show is actually a list of one object type;
specifically, the payload is just a Map of String to Object.
Once you parse the JSON,
your code will need to process each "different" payload type
based on the payload type.
Here is some sample code:
public class BlamMessage
{
private String name;
private Map<String, Object> payload;
...
}
public class MessageHolder
{
#JsonProperty("actions")
private List<BlamMessage> messageList;
private String name;
...
}

How to read values from properties file and use it in final class

Here is my final class "Constants"
#Component
public final class Constants {
#Value("${db2.schema}")
private static String Schema;
public static final String STUDENT_TABLE = Schema + ".Student";
}
I have db2.schema in my properties file :
db2.schema = ${DB2_SCHEMA}
DB2_SCHEMA = D5677ESB
#Value can not be used with static fields
You can use like:
...
public class Constants {
public static final String NewOrder = "neworder";
public static final String POST = "POST";
public static final String CONTENT_TYPE = "Content-Type";
public static final String APPLICATION_TYPE = "application/json";
public static final String ACCEPT = "Accept";
public static final String CART_URL = PropsUtil.get("order.inquiry.search.insertCartDataURL");
}
...
** or check this code:**
...
public String getPropValues() throws IOException {
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
Date time = new Date(System.currentTimeMillis());
// get the property value and print it out
String user = prop.getProperty("user");
String company1 = prop.getProperty("company1");
String company2 = prop.getProperty("company2");
String company3 = prop.getProperty("company3");
result = "Company List = " + company1 + ", " + company2 + ", " + company3;
System.out.println(result + "\nProgram Ran on " + time + " by user=" + user);
} catch (Exception e) {
System.out.println("Exception: " + e);
} finally {
inputStream.close();
}
return result;
} ...

How can i put some condition in Json parser in android studio

Here is my json URL https://jsonplaceholder.typicode.com/todos I want to display only completed: true is to be strike through, how can I do that?
MainActivity.java
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
JsonPlaceHolderApi jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
Call<List<Post>> call = jsonPlaceHolderApi.getPosts();
call.enqueue(new Callback<List<Post>>() {
#Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
if (!response.isSuccessful()) {
textresult.setText("Code: " + response.code());
return;
}
List<Post> posts = response.body();
for (Post post : posts) {
String content = "";
content += "User ID: " + post.getUserId() + "\n";
content += "ID: " + post.getId() + "\n";
content += " Title: " + post.getTitle() + "\n";
content += "Completed: " + post.getCompleted() + "\n\n";
textresult.append(content);
if (post.getCompleted().contains("true")) {
textresult.setPaintFlags(textresult.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
}
}
#Override
public void onFailure(Call<List<Post>> call, Throwable t) {
textresult.setText(t.getMessage());
}
});
JsonPlaceHolderApi.java
public interface JsonPlaceHolderApi {
#GET("todos")
Call<List<Post>> getPosts();
}
Post.java
public class Post {
private int userId;
private int id;
private String title;
private String completed;
public int getUserId() {
return userId;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getCompleted() {
return completed;
}
}
When I try to run the above code I got output as image, but I need if completed: true it should be strike.
it is not possible to do setPaintFlags() with custom text better use can use HTML text for your work for you don't need to check "post.complete()", just append all content in a single string and replace your target string (complete: true) with HTML text.
just do it like
String content = "";
for (Post post : posts) {
content += "User ID: " + post.getUserId() + "\n";
content += "ID: " + post.getId() + "\n";
content += " Title: " + post.getTitle() + "\n";
content += "Completed: " + post.getCompleted() + "\n\n";
}
String tempHtmlText = content.replaceAll("Completed: true","<strike>Completed: true</strike>");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textresult.setText(Html.fromHtml(tempHtmlText , Html.FROM_HTML_MODE_LEGACY));
} else {
textresult.setText(Html.fromHtml(tempHtmlText));
}
or you can use Gson formmater

How to parse this XML SOAP response to a POJO?

I'm having a problem converting a XML SOAP return to a corresponding POJO class. The XML return looks like this:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header></env:Header>
<env:Body>
<ns2:teste xmlns:ns2="http://teste.com.br/">
<retorno>
<codigoRetorno>000</codigoRetorno>
<descricao>Consulta Realizada com Sucesso</descricao>
<item>
<a>teste</a>
<b>teste</b>
<c>teste</c>
</item>
<item>
<a>teste</a>
<b>teste</b>
<c>teste</c>
</item>
</retorno>
</ns2:teste >
</env:Body>
</env:Envelope>
I tried to use the Jackson XMLmapper, but I can not get it to consider the 'RETURN' node as the ROOT element during deserialization. it considers the 'Envelope' node as ROOT node.
I need to extract just the return node and convert to my pojo class.
Another problem is that 'item' nodes should be part of a collection, however there is no parent node grouping these elements.
Does anyone know of a parser that does deserialization of this type of xml?
You can incorporate a streaming XML Parser (StAX) and XmlMapper in this way:
import java.io.StringReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Deser {
// #formatter:off
private static final String JSON = " <env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <env:Header></env:Header>\n" +
" <env:Body>\n" +
" <ns2:teste xmlns:ns2=\"http://teste.com.br/\">\n" +
" <retorno>\n" +
" <codigoRetorno>000</codigoRetorno>\n" +
" <descricao>Consulta Realizada com Sucesso</descricao>\n" +
" <item>\n" +
" <a>teste</a>\n" +
" <b>teste</b>\n" +
" <c>teste</c>\n" +
" </item>\n" +
" <item>\n" +
" <a>teste</a>\n" +
" <b>teste</b>\n" +
" <c>teste</c>\n" +
" </item>\n" +
" </retorno>\n" +
" </ns2:teste >\n" +
" </env:Body>\n" +
"</env:Envelope>";
// #formatter:on
private static final String TARGET_ELEMENT = "retorno";
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
XMLInputFactory f = XMLInputFactory.newFactory();
XMLStreamReader sr = f.createXMLStreamReader(new StringReader(JSON));
while (sr.hasNext()) {
int type = sr.next();
if (type == XMLStreamReader.START_ELEMENT && TARGET_ELEMENT.equals(sr.getLocalName())) {
Retorno r = xmlMapper.readValue(sr, Retorno.class);
System.out.println(r.getDescricao());
}
}
}
}
class Retorno {
private int codigoRetorno;
private String descricao;
public int getCodigoRetorno() {
return codigoRetorno;
}
public void setCodigoRetorno(int codigoRetorno) {
this.codigoRetorno = codigoRetorno;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
}
This yields:
Consulta Realizada com Sucesso
Adapt the code as necessary, this is just to prove out how to get it to do what you need!
The cleanest solution I found was using JSOUP:
private <T> T parseResponse(HttpEntity entity, Class<T> typeTarget) throws Exception {
try {
String xmlSoapResponse = EntityUtils.toString(entity, StandardCharsets.UTF_8);
String xmlRetorno = extractXmlElement(xmlSoapResponse, "retorno");
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
xmlMapper.registerModule(new JavaTimeModule());
return xmlMapper.readValue(xmlRetorno.toString(), typeTarget);
} catch (Exception e) {
throw new Exception("Fail during parser", e);
}
}
private String extractXmlElement(String xmlString, String nodeTagNameElement) {
Document document = Jsoup.parse(xmlString, "", Parser.xmlParser());
document.outputSettings().prettyPrint(false);
Elements retorno = document.getElementsByTag(nodeTagNameElement);
return retorno.toString();
}

Trouble mapping JSON data to Java object

I'm having a little trouble working out an appropriate java object structure for the following JSON data:
"pages": {
"181382": {
"pageid": 181382,
"ns": 0,
"title": "Anonymity"
},
"7181837": {
"pageid": 7181837,
"ns": 0,
"title": "Anonymous"
}
}
The identifiers "181382" and "7181837" change depending on the data returned so these cannot be used as a member on an object. I tried to approach it using a Map<String, Object> approach but got a little stuck.
Edit:
This is what I've tried
public class PageData {
int pageid;
String ns;
String title;
public int getPageid() {
return pageid;
}
public String getNs() {
return ns;
}
public String getTitle() {
return title;
}
}
Map<String, PageData> pages = results.getPages().getData();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
Just create some wrapper for your Object. Here is working example:
Wrapper
public class Wrapper {
Map<String, PageData> pages = null;
public Map<String, PageData> getPages() {
return pages;
}
}
Launcher
public class Launcher {
public static void main(String[] args) {
String str = "{\"pages\": {\r\n" +
" \"181382\": {\r\n" +
" \"pageid\": 181382,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymity\"\r\n" +
" },\r\n" +
" \"7181837\": {\r\n" +
" \"pageid\": 7181837,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymous\"\r\n" +
" }\r\n" +
" }" +
"}";
Gson gson = new Gson();
Wrapper results = gson.fromJson(str, Wrapper.class);
Map<String, PageData> pages = results.getPages();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
}
}
PageData
public class PageData{/* the same */}
Output:
Anonymity
Anonymous

Categories