From bd8a06a38b5827a43f106ec274ebbff9448096e2 Mon Sep 17 00:00:00 2001 From: jcook02 Date: Fri, 24 May 2024 13:06:04 +0200 Subject: [PATCH 1/2] BAEL-7864 - How to convert org.w3c.dom.Document to String in Java --- .../xml/xml2string/XmlDocumentToString.java | 54 +++++++++++++++++++ .../XMLStringToDocumentObjectUnitTest.java | 2 +- .../xml2string/XMLObjectToStringUnitTest.java | 2 +- .../XmlDocumentToStringUnitTest.java | 32 +++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 xml-2/src/main/java/com/baeldung/xml/xml2string/XmlDocumentToString.java create mode 100644 xml-2/src/test/java/com/baeldung/xml/xml2string/XmlDocumentToStringUnitTest.java diff --git a/xml-2/src/main/java/com/baeldung/xml/xml2string/XmlDocumentToString.java b/xml-2/src/main/java/com/baeldung/xml/xml2string/XmlDocumentToString.java new file mode 100644 index 000000000000..8e46d6fe37e7 --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/xml2string/XmlDocumentToString.java @@ -0,0 +1,54 @@ +package com.baeldung.xml.xml2string; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +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.InputSource; +import org.xml.sax.SAXException; + +public class XmlDocumentToString { + + public static final String FRUIT_XML = "AppleRed1507"; + + public static Document getDocument() throws SAXException, IOException, ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + Document document = factory.newDocumentBuilder() + .parse(new InputSource(new StringReader(FRUIT_XML))); + return document; + } + + public static String toString(Document document) throws TransformerException { + StringWriter stringWriter = new StringWriter(); + getTransformer().transform(new DOMSource(document), new StreamResult(stringWriter)); + return stringWriter.toString(); + } + + public static String toStringWithOptions(Document document) throws TransformerException { + Transformer transformer = getTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + StringWriter stringWriter = new StringWriter(); + transformer.transform(new DOMSource(document), new StreamResult(stringWriter)); + return stringWriter.toString(); + } + + private static Transformer getTransformer() throws TransformerConfigurationException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + return transformerFactory.newTransformer(); + } + +} diff --git a/xml-2/src/test/java/com/baeldung/xml/xml2document/XMLStringToDocumentObjectUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/xml2document/XMLStringToDocumentObjectUnitTest.java index f573e1c96d25..9d658b21525c 100644 --- a/xml-2/src/test/java/com/baeldung/xml/xml2document/XMLStringToDocumentObjectUnitTest.java +++ b/xml-2/src/test/java/com/baeldung/xml/xml2document/XMLStringToDocumentObjectUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.xml2document; +package com.baeldung.xml.xml2document; import org.junit.Test; import org.w3c.dom.*; diff --git a/xml-2/src/test/java/com/baeldung/xml/xml2string/XMLObjectToStringUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/xml2string/XMLObjectToStringUnitTest.java index 0afa3424f3dc..925a135775d9 100644 --- a/xml-2/src/test/java/com/baeldung/xml/xml2string/XMLObjectToStringUnitTest.java +++ b/xml-2/src/test/java/com/baeldung/xml/xml2string/XMLObjectToStringUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.xml2string; +package com.baeldung.xml.xml2string; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; diff --git a/xml-2/src/test/java/com/baeldung/xml/xml2string/XmlDocumentToStringUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/xml2string/XmlDocumentToStringUnitTest.java new file mode 100644 index 000000000000..4f342bd9b4bc --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/xml2string/XmlDocumentToStringUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.xml.xml2string; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.w3c.dom.Document; + +public class XmlDocumentToStringUnitTest { + + @Test + public void givenXMLDocument_thenConvertToStringSuccessfully() throws Exception { + Document document = XmlDocumentToString.getDocument(); + + String expectedDeclartion = ""; + assertEquals(expectedDeclartion + XmlDocumentToString.FRUIT_XML, XmlDocumentToString.toString(document)); + } + + @Test + public void givenXMLDocument_thenConvertToStringWithOutputOptionsSuccessfully() throws Exception { + Document document = XmlDocumentToString.getDocument(); + + String expected = + "\n" + + " Apple\n" + + " Red\n" + + " 150\n" + + " 7\n" + + "\n"; + assertEquals(expected, XmlDocumentToString.toStringWithOptions(document)); + } + +} From 89e122c725eed353d1f2b33ec3835c952880eb3c Mon Sep 17 00:00:00 2001 From: jcook02 Date: Fri, 19 Jul 2024 12:35:36 +0200 Subject: [PATCH 2/2] BAEL-7944 - Sort JSON Object in Java --- json-modules/json-operations/README.md | 2 + json-modules/json-operations/pom.xml | 33 ++++++ .../java/com/baeldung/sorting/SolarEvent.java | 103 ++++++++++++++++++ .../baeldung/sorting/SolarEventContainer.java | 20 ++++ .../sorting/JsonObjectSortingUnitTest.java | 75 +++++++++++++ .../src/test/resources/solar_events.json | 44 ++++++++ json-modules/pom.xml | 3 +- 7 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 json-modules/json-operations/README.md create mode 100644 json-modules/json-operations/pom.xml create mode 100644 json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEvent.java create mode 100644 json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEventContainer.java create mode 100644 json-modules/json-operations/src/test/java/com/baeldung/sorting/JsonObjectSortingUnitTest.java create mode 100644 json-modules/json-operations/src/test/resources/solar_events.json diff --git a/json-modules/json-operations/README.md b/json-modules/json-operations/README.md new file mode 100644 index 000000000000..512b64d9b27e --- /dev/null +++ b/json-modules/json-operations/README.md @@ -0,0 +1,2 @@ +## Relevant Articles + diff --git a/json-modules/json-operations/pom.xml b/json-modules/json-operations/pom.xml new file mode 100644 index 000000000000..fc9f01e4347d --- /dev/null +++ b/json-modules/json-operations/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + org.baeldung + json-operations + json-operations + + + com.baeldung + json-modules + 1.0.0-SNAPSHOT + + + + + com.google.code.gson + gson + ${gson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + 2.11.0 + + + diff --git a/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEvent.java b/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEvent.java new file mode 100644 index 000000000000..457fde006388 --- /dev/null +++ b/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEvent.java @@ -0,0 +1,103 @@ +package com.baeldung.sorting; + +import com.fasterxml.jackson.annotation.JsonProperty; + +class SolarEvent { + + @JsonProperty("event_name") + private String eventName; + @JsonProperty("date") + private String date; + @JsonProperty("coordinates") + private Coordinates coordinates; + @JsonProperty("type") + private String type; + @JsonProperty("class") + private String eventClass; + @JsonProperty("size") + private String size; + @JsonProperty("speed_km_per_s") + private int speedKmPerS; + + public String getEventName() { + return eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public Coordinates getCoordinates() { + return coordinates; + } + + public void setCoordinates(Coordinates coordinates) { + this.coordinates = coordinates; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getEventClass() { + return eventClass; + } + + public void setEventClass(String eventClass) { + this.eventClass = eventClass; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public int getSpeedKmPerS() { + return speedKmPerS; + } + + public void setSpeedKmPerS(int speedKmPerS) { + this.speedKmPerS = speedKmPerS; + } +} + +class Coordinates { + + @JsonProperty("latitude") + private double latitude; + + @JsonProperty("longitude") + private double longitude; + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + +} diff --git a/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEventContainer.java b/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEventContainer.java new file mode 100644 index 000000000000..b347ac777af3 --- /dev/null +++ b/json-modules/json-operations/src/main/java/com/baeldung/sorting/SolarEventContainer.java @@ -0,0 +1,20 @@ +package com.baeldung.sorting; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SolarEventContainer { + + @JsonProperty("solar_events") + private List solarEvents; + + // Getters and setters + public List getSolarEvents() { + return solarEvents; + } + + public void setSolarEvents(List solarEvents) { + this.solarEvents = solarEvents; + } +} diff --git a/json-modules/json-operations/src/test/java/com/baeldung/sorting/JsonObjectSortingUnitTest.java b/json-modules/json-operations/src/test/java/com/baeldung/sorting/JsonObjectSortingUnitTest.java new file mode 100644 index 000000000000..e61ef7d1f86e --- /dev/null +++ b/json-modules/json-operations/src/test/java/com/baeldung/sorting/JsonObjectSortingUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.sorting; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +class JsonObjectSortingUnitTest { + + @Test + void givenJsonObject_whenUsingJackson_thenSortedBySpeedCorrectly() throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + SolarEventContainer container = objectMapper.readValue( + new File("src/test/resources/solar_events.json"), SolarEventContainer.class); + + List events = container.getSolarEvents(); + Collections.sort(events, Comparator.comparingInt(event -> event.getSpeedKmPerS())); + + assertEquals(100, events.get(0) + .getSpeedKmPerS()); + assertEquals(500, events.get(1) + .getSpeedKmPerS()); + assertEquals(1000, events.get(2) + .getSpeedKmPerS()); + assertEquals(1500, events.get(3) + .getSpeedKmPerS()); + } + + @Test + public void givenJsonObject_whenUsingGson_thenSortedBySizeCorrectly() throws FileNotFoundException { + JsonReader reader = new JsonReader(new FileReader("src/test/resources/solar_events.json")); + JsonElement element = JsonParser.parseReader(reader); + JsonArray events = element.getAsJsonObject().getAsJsonArray("solar_events"); + List list = events.asList(); + + Collections.sort(list, (a, b) -> { + double latA = a.getAsJsonObject() + .getAsJsonObject("coordinates") + .get("latitude") + .getAsDouble(); + double latB = b.getAsJsonObject() + .getAsJsonObject("coordinates") + .get("latitude") + .getAsDouble(); + return Double.compare(latA, latB); + }); + + assertEquals(-5, getJsonAttributeAsInt(list.get(0))); + assertEquals(0, getJsonAttributeAsInt(list.get(1))); + assertEquals(15, getJsonAttributeAsInt(list.get(2))); + assertEquals(37, getJsonAttributeAsInt(list.get(3))); + } + + private int getJsonAttributeAsInt(JsonElement element) { + return element.getAsJsonObject() + .getAsJsonObject("coordinates") + .get("latitude") + .getAsInt(); + } + +} diff --git a/json-modules/json-operations/src/test/resources/solar_events.json b/json-modules/json-operations/src/test/resources/solar_events.json new file mode 100644 index 000000000000..d1388628e17d --- /dev/null +++ b/json-modules/json-operations/src/test/resources/solar_events.json @@ -0,0 +1,44 @@ +{ + "solar_events": [ + { + "event_name": "Solar Eclipse", + "date": "2024-04-08", + "coordinates": { + "latitude": 37.7749, + "longitude": -122.4194 + }, + "size": "Large", + "speed_km_per_s": 1000 + }, + { + "event_name": "Solar Flare", + "date": "2023-10-28", + "coordinates": { + "latitude": 0, + "longitude": 0 + }, + "size": "Small", + "speed_km_per_s": 100 + }, + { + "event_name": "Sunspot", + "date": "2023-11-15", + "coordinates": { + "latitude": 15, + "longitude": -75 + }, + "size": "Large", + "speed_km_per_s": 1500 + }, + { + "event_name": "Coronal Mass Ejection", + "date": "2024-01-10", + "coordinates": { + "latitude": -5, + "longitude": 80 + }, + "size": "Medium", + "speed_km_per_s": 500 + } + ] +} \ No newline at end of file diff --git a/json-modules/pom.xml b/json-modules/pom.xml index 70b64624d485..36f9a0fb2945 100644 --- a/json-modules/pom.xml +++ b/json-modules/pom.xml @@ -18,6 +18,7 @@ json-2 json-arrays json-conversion + json-operations json-path gson gson-2 @@ -38,4 +39,4 @@ 20240303 - \ No newline at end of file +