7

複数の XML 要素にまたがる単一の概念をモデル化している次の XML 構造があります。この形式は私の管理下にありません。

<Output>
  <Wrapper>
    <Channel>
      <id>1</id>
      <type>x</type>
    </Channel>
    <Channel>
      <id>2</id>
      <type>y</type>
    </Channel>
    <ChannelName>
      <id>1</id>
      <name>Channel name</name>
    </ChannelName>
    <ChannelName>
      <id>2</id>
      <name>Another channel name</name>
    </ChannelName>
  </Wrapper>
</Output>

私が制御できるデータベースでこれをモデル化し、 、 、およびフィールドを含むより単純なChannelテーブルを作成したいと考えています。したがって、クラスでシングルにアンマーシャリングしたいと思います。idtypenameList<Channel>Wrapper

@Xml...これは注釈で自動的に行うことができますか? 現在、JAXB を使用して個別@XmlElement(name="Channel")のクラス リストにアンマーシャリングし、トランジェントを@XmlElement(name="ChannelName")後処理していますが、これらの要素をマップするためのより簡単な自動化された方法が必要だと考えています。それともXSLTの仕事ですか?ChannelName/nameChannel

XML が HTTP ファイル POST ファイルとして入ってくること、および私が Spring 3、Java、および Hibernate を使用していることを知っておくと役立つ場合があります。EclipseLink JAXB (MOXy)の何かが役立つことを願っています:)

4

2 に答える 2

13

@XmlElementWrapper は仕事をします:

@XmlElementWrapper(name="Wrapper")
@XmlElement(name="Channel")
private List<Channel> channels;

より高度なケースでは、EclipseLink JAXB (MOXy) で @XmlPath 拡張機能を使用できます。


これが私がこれまでに持っているものです。私はまだヘルパー オブジェクトの必要性を排除しようとしています。この例では、EclipseLink JAXB (MOXy)が必要です。

モデル オブジェクト

モデル オブジェクトは次のとおりです。

package example;

import java.util.ArrayList;
import java.util.List;

public class Wrapper {

    private List<Channel> channels = new ArrayList<Channel>();

    public List<Channel> getChannels() {
        return channels;
    }

    public void setChannels(List<Channel> channels) {
        this.channels = channels;
    }

}

と:

package example;

import javax.xml.bind.annotation.XmlID;

public class Channel {

    private String id;
    private String type;
    private String name;

    @XmlID
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

ヘルパー オブジェクト

私の現在のソリューションには、いくつかのヘルパー オブジェクトが含まれます。

package example.adapted;

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import example.Channel;
import example.Wrapper;

@XmlRootElement(name="Output")
@XmlType(propOrder={"channels", "channelNames"})
public class AdaptedWrapper {

    private Wrapper wrapper = new Wrapper();
    private List<ChannelName> channelNames;

    @XmlTransient
    public Wrapper getWrapper() {
        for(ChannelName channelName : channelNames) {
            channelName.getChannel().setName(channelName.getName());
        }
        return wrapper;
    }

    @XmlElementWrapper(name="Wrapper")
    @XmlElement(name="Channel")
    public List<Channel> getChannels() {
        return wrapper.getChannels();
    }

    public void setChannels(List<Channel> channels) {
        wrapper.setChannels(channels);
    }

    @XmlElementWrapper(name="Wrapper")
    @XmlElement(name="ChannelName")
    public List<ChannelName> getChannelNames() {
        return channelNames;
    }

    public void setChannelNames(List<ChannelName> channelNames) {
        this.channelNames = channelNames;
    }

}

と:

package example.adapted;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlIDREF;

import example.Channel;

public class ChannelName {

    private String name;
    private Channel channel;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlIDREF
    @XmlElement(name="id")
    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

}

デモコード

package example;

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import example.adapted.AdaptedWrapper;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(AdaptedWrapper.class);

        File xml = new File("input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        AdaptedWrapper adaptedWrapper = (AdaptedWrapper) unmarshaller.unmarshal(xml);
        Wrapper wrapper = adaptedWrapper.getWrapper();

        for(Channel channel : wrapper.getChannels()) {
            System.out.println(channel.getName());
        }
    }

}
于 2011-03-16T12:42:30.327 に答える
2

JAXB でこのプロセスを自動化することにより、コーディング時間を節約できます。

以下のリンクを使用して XML の XML スキーマを作成し、 output.xsdファイル として保存します: http://www.xmlforasp.net/CodeBank/System_Xml_Schema/BuildSchema/BuildXMLSchema.aspx

JDK のみがxjc.exeツールを備えているため (必要な詳細を入力します)、JDK を使用して、プロジェクトのルート フォルダー (.) から以下のバッチ スクリプト ファイル ( output.batという名前) を実行します。

"C:\Program Files\Java\jdk1.6.0_24\bin\xjc.exe" -p %1 %2 -d %3

どこ...

syntax: output.bat %1 %2 %3
%1 = target package name
%2 = full file path name of the generated XML schema .xsd 
%3 = root source folder to store generated JAXB java files

例:

プロジェクトフォルダーが次のように編成されているとしましょう:

.
\_src

(.) からコマンド プロンプトで次のコマンドを実行します。

output.bat com.project.xml .\output.xsd .\src

いくつかのファイルが作成されます。

.
\_src
  \_com
    \_project
      \_xml
        |_ObjectFactory.java
        |_Output.java

次に、以下のいくつかの便利なメソッドを作成して、Outputオブジェクトを操作できます。

private JAXBContext jaxbContext = null;
private Unmarshaller unmarshaller = null;
private Marshaller marshaller = null;

public OutputManager(String packageName) {
    try {
        jaxbContext = JAXBContext.newInstance(packageName);
        unmarshaller = jaxbContext.createUnmarshaller();
        marshaller = jaxbContext.createMarshaller();
    } catch (JAXBException e) {
    }
}

public Output loadXML(InputStream istrm) {

    Output load = null;

    try {
        Object o = unmarshaller.unmarshal(istrm); 

        if (o != null) {

            load = (Output) o;

        }

    } catch (JAXBException e) {

        JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);

    }
    return load;
}

public void saveXML(Object o, java.io.File file) {

    Output save = null;

    try {
        save = (Output) o;

        if (save != null) {
            marshaller.marshal(save, file);
        }

    } catch (JAXBException e) {

        JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);

    }
}

public void saveXML(Object o, FileOutputStream ostrm) {

    Output save = null;

    try {

        save = (Output) o;

        if (save != null) {
            marshaller.marshal(save, ostrm);
        }

    } catch (JAXBException e) {

        JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), e.getClass().getSimpleName(), JOptionPane.ERROR_MESSAGE);

    }
}
于 2011-03-16T14:39:25.027 に答える