Skip to content

Instantly share code, notes, and snippets.

@uemuraj
Created September 13, 2020 05:23
Show Gist options
  • Save uemuraj/5d284a4d2b3755d3962b9eba7e6c882f to your computer and use it in GitHub Desktop.
Save uemuraj/5d284a4d2b3755d3962b9eba7e6c882f to your computer and use it in GitHub Desktop.
気象庁防災情報XMLからJSONへの変換
package jp.aitc.jmardb;
import java.io.OutputStream;
import java.lang.reflect.Member;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.transform.Source;
import jp.go.kishou.xml.jmaxml1.TypeReport;
import jp.go.kishou.xml.jmaxml1.elementbasis1.TypeDateTime;
import net.arnx.jsonic.JSON;
/**
* 気象防災情報XMLをJSONに変換する。
*/
public class Report2Json {
private JSON json = new JSON() {
{
setSuppressNull(true);
}
@Override
protected boolean ignore(Context context, Class<?> clazz, Member member) {
// 以下のメンバは JSON には含めない
String name = member.getName();
if (name.equals("getXMLSchemaType")) {
return true;
}
return super.ignore(context, clazz, member);
}
@Override
protected Object preformat(Context context, Object value)
throws Exception {
// 以下の型は出力を簡略化する
if (value instanceof XMLGregorianCalendar) {
return value.toString();
}
if (value instanceof Duration) {
return value.toString();
}
if (value instanceof TypeDateTime) {
return preformat(context, ((TypeDateTime) value).getValue());
}
return super.preformat(context, value);
}
};
private JAXBContext context;
private Unmarshaller unmarshaller;
/**
* コンストラクタ。
*/
public Report2Json() throws Exception {
context = JAXBContext.newInstance(TypeReport.class);
unmarshaller = context.createUnmarshaller();
}
/**
* 気象防災情報XMLをJSONに変換する。
*
* @param source
* {@link Source}
* @param result
* {@link Appendable}
*/
public synchronized void transform(Source source, Appendable result)
throws Exception {
json.format(new Wrapper(source), result);
}
/**
* 気象防災情報XMLをJSONに変換する。
*
* @param source
* {@link Source}
* @param result
* {@link OutputStream}
*/
public synchronized void transform(Source source, OutputStream result)
throws Exception {
json.format(new Wrapper(source), result);
}
// 簡単なラッパーを使って JSON の外枠を作ります
public class Wrapper {
final JAXBElement<TypeReport> report;
Wrapper(Source source) throws Exception {
report = unmarshaller.unmarshal(source, TypeReport.class);
}
public TypeReport getReport() {
return report.getValue();
}
}
}
@uemuraj
Copy link
Author

uemuraj commented Sep 13, 2020

気象庁防災情報 XML で JAXB する時の注意点 (1)

Body に実際のインスタンスを入れてもらうため、 @XmlElementRef を入れる必要がある。
また、JSON 化する際は getter/setter の名前が見られるため、名前を変えておく。

public class TypeReport {

    @XmlElement(name = "Control", required = true)
    protected TypeControl control;

    @XmlElement(name = "Head", namespace = "http://xml.kishou.go.jp/jmaxml1/informationBasis1/" , required = true)
    protected TypeHead head;

    @XmlAnyElement(lax = true)
    @XmlElementRefs({
        @XmlElementRef(name="Body", namespace="http://xml.kishou.go.jp/jmaxml1/body/meteorology1/" , type=jp.go.kishou.xml.jmaxml1.body.meteorology1.TypeBody.class),
        @XmlElementRef(name="Body", namespace="http://xml.kishou.go.jp/jmaxml1/body/seismology1/" , type=jp.go.kishou.xml.jmaxml1.body.seismology1.TypeBody.class),
        @XmlElementRef(name="Body", namespace="http://xml.kishou.go.jp/jmaxml1/body/volcanology1/" , type=jp.go.kishou.xml.jmaxml1.body.volcanology1.TypeBody.class)
      })
    protected Object any;

@uemuraj
Copy link
Author

uemuraj commented Sep 13, 2020

気象庁防災情報 XML で JAXB する時の注意点 (2)

3種類の Body が定義されるが、それぞれのクラスで @XmlRootElement を追加する。
この要素の構築方法がプロセッサに見えるようにする必要がある。

@XmlRootElement(name="Body" , namespace="http://xml.kishou.go.jp/jmaxml1/body/meteorology1/" )
@XmlAccessorType(XmlAccessType.FIELD )
@XmlType(name = "type.Body", propOrder = {
    "targetArea",
    "notice",
    "warning",
    "meteorologicalInfos",
    "comment",
    "officeInfo",
    "additionalInfo"
})
public class TypeBody {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment