All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.offerready.xslt.JsonXmlConverter Maven / Gradle / Ivy

The newest version!
package com.offerready.xslt;

import lombok.extern.slf4j.Slf4j;
import org.json.*;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.annotation.Nonnull;
import java.io.*;
import java.util.regex.Pattern;
import java.util.stream.StreamSupport;

import static com.databasesandlife.util.DomParser.newDocumentBuilder;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.regex.Matcher.quoteReplacement;
import static java.util.stream.Collectors.toMap;

/**
 * Converts between JSON and XML.
 *   

* The default libraries use "content":"xyz" for the body of XML tags, we use "_content" * so that JSON with actual "content":"xyz" can be parsed into <content>xyz</content> */ @Slf4j public class JsonXmlConverter { protected static final XMLParserConfiguration config = XMLParserConfiguration.ORIGINAL.withcDataTagName("_content"); protected static final Pattern patternFirstChar = Pattern.compile("^[^a-zA-Z_]"); protected static final Pattern patternNonFirstChar = Pattern.compile("[^a-zA-Z0-9-_.]"); protected @Nonnull String makeKeySafeForXml(@Nonnull Pattern pattern, @Nonnull String key) { var result = new StringBuilder(); var matcher = pattern.matcher(key); while (matcher.find()) { var c = matcher.group(); assert c.length() == 1; matcher.appendReplacement(result, quoteReplacement(String.format("_%04x_", (int) c.toCharArray()[0]))); } matcher.appendTail(result); return result.toString(); } /** * Alter JSON to have keys which are safe as XML element names. * JSON objects can have keys such as "foo bar" but XML elements cannot have keys such as <foo bar>. * The default JSON-to-XML converter simply converts JSON object keys to XML element names verbatim. */ protected @Nonnull Object makeKeysInJsonSafeForXml(@Nonnull Object input) { if (input instanceof JSONObject o) return new JSONObject(o.keySet().stream().collect(toMap( key -> makeKeySafeForXml(patternNonFirstChar, makeKeySafeForXml(patternFirstChar, key)), key -> makeKeysInJsonSafeForXml(o.opt(key)) ))); else if (input instanceof JSONArray a) return new JSONArray(StreamSupport.stream(a.spliterator(), false) .map(e -> makeKeysInJsonSafeForXml(e)) .toList()); else return input; } public @Nonnull Element convertJsonToXml(@Nonnull Reader json, @Nonnull String rootElement) throws JSONException, IOException { var jsonObject = new JSONTokener(json).nextValue(); var jsonObjectWithSafeKeys = makeKeysInJsonSafeForXml(jsonObject); var xmlString = XML.toString(jsonObjectWithSafeKeys, rootElement, config); try { return newDocumentBuilder().parse(new InputSource(new StringReader(xmlString))).getDocumentElement(); } catch (SAXException e) { log.info("JSON converted to XML: " + xmlString); throw new JSONException(e); } } public @Nonnull Element convertJsonToXml(@Nonnull String contentType, @Nonnull InputStream jsonInputStream, @Nonnull String rootElement) throws JSONException, IOException { var charset = com.google.common.net.MediaType.parse(contentType).charset().or(UTF_8); try (var reader = new InputStreamReader(jsonInputStream, charset)) { return convertJsonToXml(reader, rootElement); } } public @Nonnull String convertXmlToJson(@Nonnull String xml) { var json = XML.toJSONObject(xml, config); return json.toString(2); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy