Converting Hl7 message to Json - java

i need to convert the HL7 message to JSON so i used Hapi to convert the message to xml and then used a JSON library to convert the xml to JSON,The output for xml is
<?xml version="1.0" encoding="UTF-8"?>
<ADT_A01 xmlns="urn:hl7-org:v2xml">
<MSH>
<MSH.1>|</MSH.1>
<MSH.2>^~\&</MSH.2>
<MSH.3>
<HD.1>7EDIT</HD.1>
</MSH.3>
<MSH.4>
<HD.1>7EDIT.COM</HD.1>
</MSH.4>
<MSH.5>
<HD.1>IS</HD.1>
</MSH.5>
<MSH.6>
<HD.1>FACILITY</HD.1>
</MSH.6>
<MSH.7>20150721160705</MSH.7>
<MSH.8>S</MSH.8>
<MSH.9>
<MSG.1>ADT</MSG.1>
<MSG.2>A01</MSG.2>
</MSH.9>
<MSH.10>MSG00001</MSH.10>
<MSH.11>
<PT.1>P</PT.1>
</MSH.11>
<MSH.12>
<VID.1>2.6</VID.1>
</MSH.12>
<MSH.13>1</MSH.13>
<MSH.14>ST</MSH.14>
<MSH.15>AL</MSH.15>
<MSH.16>AL</MSH.16>
<MSH.17>972</MSH.17>
<MSH.18>WINDOWS-1252</MSH.18>
</MSH>
<EVN>
<EVN.1>A01</EVN.1>
<EVN.2>20150721160852</EVN.2>
<EVN.3>20150721160854</EVN.3>
<EVN.4>01</EVN.4>
<EVN.5>
<XCN.1>st</XCN.1>
</EVN.5>
<EVN.6>20150721160917</EVN.6>
<EVN.7>
<HD.1>IS</HD.1>
</EVN.7>
</EVN>
<PID>
<PID.1>1</PID.1>
<PID.2>
<CX.1>ST</CX.1>
<CX.4>
<HD.1>IS</HD.1>
</CX.4>
</PID.2>
<PID.3>
<CX.1>12345</CX.1>
</PID.3>
<PID.5>
<XPN.1>
<FN.1>JOSEPH</FN.1>
</XPN.1>
</PID.5>
</PID>
<PV1>
<PV1.2>B</PV1.2>
<PV1.3>
<PL.1>IS</PL.1>
</PV1.3>
<PV1.4>A</PV1.4>
<PV1.5>
<CX.1>S</CX.1>
</PV1.5>
<PV1.6>
<PL.1>S2</PL.1>
</PV1.6>
<PV1.7>
<XCN.1>REALM</XCN.1>
</PV1.7>
<PV1.8>
<XCN.1>HANNAH</XCN.1>
</PV1.8>
<PV1.9>
<XCN.1>DOCTOR</XCN.1>
</PV1.9>
<PV1.10>SUR</PV1.10>
<PV1.11>
<PL.1>PC</PL.1>
</PV1.11>
<PV1.12>S</PV1.12>
<PV1.13>R</PV1.13>
<PV1.14>7</PV1.14>
<PV1.15>A0</PV1.15>
<PV1.16>IN</PV1.16>
<PV1.17>
<XCN.1>NUMBER</XCN.1>
</PV1.17>
<PV1.18>AM</PV1.18>
<PV1.19>
<CX.1>NUM</CX.1>
</PV1.19>
<PV1.20>
<FC.1>FC</FC.1>
</PV1.20>
<PV1.21>PR</PV1.21>
<PV1.22>S</PV1.22>
<PV1.23>SS</PV1.23>
<PV1.24>S</PV1.24>
</PV1>
</ADT_A01>
Here the output is like segmenName.FieldName (MSH.1),so the Json is also the same ,instead of segmenName.FieldName ,i need to give a meanigful name to each field, i am unable to figure out how to do this
i need to map the element in Xml to a different key in JSON

One way of doing this is to have a mapping of fields/names, and traverse all your JSON looking for fields on the mapping, when a field is found, change it's name to the correspondent name in the mapping.
You might not be able to change the JSON you are traversing, in that case, the traverse should be cloning the structure, creating JSON nodes with the correspondent names.
Your JSON tool might have a way of parsing and traversing the whole JSON object recursively.
Another way is that you implement the XML-JSON conversion (it is really simple to do), and include the "name mapping" step into that conversion.

Related

how to create the data model for this { "words":[3,4,5] } json in kotlin

I was trying to write a data model to send a JSON to the API and delete some fields
the JSON should contain the id of some words and it should look exactly like this :
{
"words":[3,4,5]
}
as I know and also as the https://jsonformatter.org/ said the data class should be something like the following piece of code:
data class words(var id: List<Int>)
but the problem is when I pass the data to it and toast it to see if it's a valid JSON request for the server the output will be this :
words(id=[1,2,4,5])
and it's not what it should be.
as I said I need this :
{
"words":[3,4,5]
}
I think the following should work.
data class AnyNameYouWant(val words: List<Int>)
I think the name of the data class really doesn't matter as it would finally represent the { } object syntax of json.
Looking in the comments, I think it's better to use some logging library like Timber. If you are using Retrofit then use can also use HttpLoggingInterceptor and set the level to Body that will print the body of the response in the logcat.

Sending JSON with enum data types

I am trying to send a json with a data type that is a enum according to the ebay documantion here:
http://developer.ebay.com/devzone/rest/api-ref/inventory/types/OperatingHours.html
The field in question is the dayOfWeekEnum, which I tried sending in my JSON several ways:
{"dayOfWeekEnum": "FRIDAY"}
{"dayOfWeekEnum": 0}
{"dayOfWeekEnum": {"dayOfWeekEnum": "FRIDAY"}}
And none of them didn't work. I alwyas get the message saying it could not serialize the field dayOfWeekEnum:
[{"errorId"=>2004, "domain"=>"ACCESS", "category"=>"REQUEST", "message"=>"Invalid request", "longMessage"=>"The request has errors. For help, see the documentation for this API.", "parameters"=>[{"name"=>"reason", "value"=>"Could not serialize field [operatingHours.dayOfWeekEnum]"}]}]
I am assuming ebay runs a Java api, so how should I send my JSON enum info properly?
I know from experience that eBay's documentation can be wrong when it comes to the names of fields. Have you tried passing dayOfWeek instead of dayOfWeekEnum?

Retrofit 2 How to parse XML without a root element

This is the response that I want to parse :
<paste>
<paste_key>UW369pYh</paste_key>
<paste_date>1478837545</paste_date>
<paste_title>10/11/2016 - KTOS</paste_title>
<paste_size>16201</paste_size>
<paste_expire_date>0</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_short>text</paste_format_short>
<paste_format_long>None</paste_format_long>
<paste_url>http://pastebin.com/UW369pYh</paste_url>
<paste_hits>5869</paste_hits>
</paste>
<paste>
<paste_key>NqQTQeYj</paste_key>
<paste_date>1478968384</paste_date>
<paste_title>Buffs/Nerfs de las megas en S&M</paste_title>
<paste_size>2232</paste_size>
<paste_expire_date>0</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_short>text</paste_format_short>
<paste_format_long>None</paste_format_long>
<paste_url>http://pastebin.com/NqQTQeYj</paste_url>
<paste_hits>589</paste_hits>
</paste>
<paste>
<paste_key>xnrqJF59</paste_key>
<paste_date>1478849206</paste_date>
<paste_title>Lista_Mario_PT.m3u</paste_title>
<paste_size>6079</paste_size>
<paste_expire_date>0</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_short>cpp</paste_format_short>
<paste_format_long>C++</paste_format_long>
<paste_url>http://pastebin.com/xnrqJF59</paste_url>
<paste_hits>1928</paste_hits>
</paste>
<paste>
<paste_key>RHrCmtpG</paste_key>
<paste_date>1478717113</paste_date>
<paste_title>Rigged US Elections 2016</paste_title>
<paste_size>1341</paste_size>
<paste_expire_date>0</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_short>text</paste_format_short>
<paste_format_long>None</paste_format_long>
<paste_url>http://pastebin.com/RHrCmtpG</paste_url>
<paste_hits>8463</paste_hits>
</paste>
As you can see, there is no root element, only a list of paste elements. Right now I am using the response type as Paste, and can only parse the first element of the response.
How can I parse the whole response into a List<Paste> object ?
You can try to use custom parsers to parse a response. It's a kind of boilerplate solution. You need to write a common and not reusable code. Check another answer for more details about custom parsers for Retrofit2.

Java DOM XML Parser with chaning namespaces

I do REST calls to a WebService and receive always XML as response. Then i'm parsing that XML und filling Java objects with those informations.
The Problem is that the element-tags could have different namespaces, like this:
<ns:title>....</ns:title>
or
<ns2:title>....<ns2:title>
or
<title>...<title>
EDIT:
And the namespace URIs look like this:
<ns2:feed xmlns="http://www.example.com/routing1/routing2"
xmlns:ns2="http://www.w3.org/../Atom"
xmlns:ns3="http://www.example.com/routing1/routing2"
xmlns:ns4="http://purl.org/routing1/routing2/1.0">
So therefore i changed the method element.getElementsByTagNameNS("specifiedNamespace", "title") to element.getElementsByTagNameNS("*", "title").
Is that okay to match all namespace, because i have also the case that the element-tag doesn't have a namespace like the third example <title>..</title>..
Is there a better procedure, to solve that problem? Or is it okay to solve it like, how i do it?
Thanks.
EDIT: 2 response examples
1.
<ns2:feed xmlns="http://www.example.com/routing1/routing2" xmlns:ns2="http://www.w3.org/../Atom" xmlns:ns3="http://www.example.com/routing1/routing2" xmlns:ns4="http://purl.org/routing1/routing2/1.0">
...
<ns2:someTag1>..</ns2:someTag1>
<ns2:title>title</ns2:title>
<entry>...</entry>
....
</ns2:feed>
2
<ns2:feed xmlns="http://www.w3.org/../Atom" xmlns:ns2="http://www.example.com/routing1/routing2" xmlns:ns3="http://www.example.com/routing1/routing2" xmlns:ns4="http://purl.org/routing1/routing2/1.0">
...
<someTag1>..<someTag1>
<title>title<title>
<ns2:entry>...</ns2:entry>
....
</ns2:feed>
Your title elements have the same namespace in both of your examples.
In the first example, you have:
xmlns:ns2="http://www.w3.org/../Atom"
and
<ns2:title>title</ns2:title>
so this means that title is in the http://www.w3.org/../Atom namespace.
In the second example, you have:
xmlns="http://www.w3.org/../Atom"
and
<title>title<title>
so here again title is in the http://www.w3.org/../Atom namespace.
The prefixes are different (the second example isn't using a prefix for title), but the namespace is the same.
This means that you should be able to use:
element.getElementsByTagNameNS("http://www.w3.org/../Atom", "title")
and it should successfully select the title element, even if the prefixes change.

Deserialize XML in multiple objects using SimpleXML

I built xml files in Android from objects by appending multiple objects to the same file using Simple
<listOfBtDevices>
<devices class="java.util.ArrayList">
<BTDevice>
<address>00:27:13:A3:2D:14</address>
<bondState>NONE</bondState>
<deviceType>LAPTOP</deviceType>
<name>LTPH</name>
<services>AUDIO CAPTURE NETWORKING OBJECT_TRANSFER RENDERING TELEPHONY</services>
<rssi>-95</rssi>
</BTDevice>
<BTDevice>
<address>00:27:13:A3:2D:14</address>
<bondState>NONE</bondState>
<deviceType>LAPTOP</deviceType>
<name>LTPH</name>
<services>AUDIO CAPTURE NETWORKING OBJECT_TRANSFER RENDERING TELEPHONY</services>
<rssi>-95</rssi>
</BTDevice>
<BTDevice>
<address>00:27:13:A3:2D:14</address>
<bondState>NONE</bondState>
<deviceType>LAPTOP</deviceType>
<name>LTPH</name>
<services>AUDIO CAPTURE NETWORKING OBJECT_TRANSFER RENDERING TELEPHONY</services>
<rssi>-95</rssi>
</BTDevice>
</devices>
<timestamp>22.11.2013_10.56.44</timestamp>
</listOfBtDevices>
<listOfBtDevices>
<devices class="java.util.ArrayList">
<BTDevice>
<address>00:27:13:A3:2D:14</address>
<bondState>NONE</bondState>
<deviceType>LAPTOP</deviceType>
<name>LTPH</name>
<services>AUDIO CAPTURE NETWORKING OBJECT_TRANSFER RENDERING TELEPHONY</services>
<rssi>-95</rssi>
</BTDevice>
</devices>
<timestamp>22.11.2013_10.56.50</timestamp>
</listOfBtDevices>
In the example above the object is ListOfBtDevices which is compound of a (String)timestamp and an ArrayList of BTDevice. The question is how can I deserialize it in multiple ListOfBtDevice objects using Simple or other framework on the Desktop Computer?
Thank you and sorry if I made mistakes but I am beginner in JAVA.
First of all, for you to be able to deserialize the xml file it needs to have one single root node. not multiple like in your case.
You have:
<listOfBtDevices>
...
</listOfBtDevices>
<listOfBtDevices>
...
</listOfBtDevices>
What it should look like:
<root>
<listOfBtDevices>
...
</listOfBtDevices>
<listOfBtDevices>
...
</listOfBtDevices>
</root>
After that you need to deserialize using some framework like Simple or XStream. I would recommend Simple for your purposes and I will give you a rudimentary example using Simple:
To deserialize the XML into objects using Simple you have to create model classes which have the same structure like your xml. You describe how the Objects are mapped to XML using annotations like #Element or #Attribute. In your case it would look something like this:
First you need a class which corresponds to your root node:
// The name you enter here is how the root node is called in your xml
#Root(name = "root")
public class BluetoothDeviceListContainer {
// It contains a List, inline is set to true because the list items are directly inside the root node, each entry is called "listOfBtDevices"
#ElementList(entry = "listOfBtDevices", inline = true)
List<BluetoothDeviceList> bluetoothDeviceList;
}
And you continue to do this until you have fully described your xml with classes. Next you would create a Class BluetoothDeviceList which corresponds to the "listOfBtDevices" nodes and enter which elements and attributes are contained and this class etc.
When you are finished you can deserialize your xml like this:
Serializer serializer = new Persister();
BluetoothDeviceListContainer container = serializer.read(BluetoothDeviceListContainer.class, xmlAsString);
After adding some getters and if you need setters to your model classes you can access all deserialized properties like this:
BluetoothDeviceList list = container.get(0);
...
Here you can find a complete tutorial for Simple and here some additional examples.

Categories