0

私は JAXB にあまり詳しくありませんが、これは私が持っているコンテキストです。すべてを読んで理解してください。

1.このXMLからJAXBを使用して値を取得するために、次のことを行っています...

XML ドキュメント スニペット (オリジナル):

 <Request deploymentMode="production">
        <OrderRequest>
             <OrderRequestHeader orderID="12345" orderDate="2012-07-04" type="new">
                 <Total>
                     <Money currency="USD">200.0</Money>
                 </Total>
                 <ShipTo>
                     <Address>
                         <Name xml:lang="">Test</Name>
                         <PostalAddress name="default">
                             <DeliverTo/>
                             <Street>Value 1</Street>
                             <City>Value 2</City>
                             <State>Value 3</State>
                             <PostalCode>302010</PostalCode>
                             <Country isoCountryCode="US">USA</Country>
                         </PostalAddress>
                     </Address>
                 </ShipTo>

したがって、必要な値はStatefromPostalAddressであり、次のコードを使用します。

String state = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress().getState();
//This will return "Value 3"

そして、すべてがうまく機能します。

2.問題はこの時点から始まります。上記と同じことを行いますが、この XML を使用します...

XML ドキュメント スニペット (その他):

 <Request deploymentMode="production">
        <OrderRequest>
             <OrderRequestHeader orderID="12345" orderDate="2012-07-04" type="new">
                 <Total>
                     <Money currency="USD">200.0</Money>
                 </Total>
                 <ShipTo>
                     <Address>
                         <Name xml:lang="">Test</Name>
                     </Address>
                 </ShipTo>

値が存在しないことはわかっていますが、コードを変更したくなく、これを引き続き使用しています。

String state = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress().getState();

上記のコードはNullPointerException、プロセスを生成して停止します。私が必要としているのは、これが XML から抽出している唯一の値ではないため、プロセスを停止しないことです (これは、私が扱っているものの単なる例です)。したがって、値が見つからない場合は、state変数をnull自動的に設定したいと考えています。

Q:値が見つからない場合にstateのみ、例外を生成せずに文字列変数を作成する方法はありますか?null


PS。考えられる解決策は、次のようなことです。

//Fill the entity
PostalAddressType p = xml.getRequest().getOrderRequest().getOrderRequestHeader().getShipTo().getAddress().getPostalAddress();
//Variable for state
String state = null;
//Evaluate if it is null or not
if(p != null)
    //Capture the value if not null
    state = p.getState();

ifしかし、XML のすべてのエンティティーに対してステートメントを作成するのは好きではありません。私が言ったように、コードを変更せずに何かを自動化したいのですが、JAXB 構成またはこれを行うための何かがあるかどうかはわかりません。

前もって感謝します。

4

1 に答える 1

1

JAXB (JSR-222)は、オブジェクトを XML との間で変換するための Java 標準です。複数のオープンソース実装があります。JAXB が使用するオブジェクトは POJO (plain old Java objects) です。これらのクラスには、いかなる種類の XML ロジックも組み込まれていません。JAXB は既存のクラスで動作するように設計されているため、ユース ケースをサポートするために解決できるロジックがいくつかある場合があります。以下にいくつかのオプションを示します。

オプション #1 - PostalAddress プロパティの遅延読み込み (非推奨)

住所

メソッドにロジックを追加して、プロパティがgetPostalAddress()の場合のインスタンスをインスタンス化できます。PostalAddressnull

package forum11333165;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Address")
public class Address {

    private String name;
    private PostalAddress postalAddress;

    @XmlElement(name="Name")
    public String getName() {
        return name;
    }

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

    @XmlElement(name="PostalAddress")
    public PostalAddress getPostalAddress() {
        if(null == postalAddress) {
            postalAddress = new PostalAddress();
        }
        return postalAddress;
    }

    public void setPostalAddress(PostalAddress postalAddress) {
        this.postalAddress = postalAddress;
    }

}

郵便番号

package forum11333165;

import javax.xml.bind.annotation.XmlElement;

public class PostalAddress {

    private String state;

    @XmlElement(name="State")
    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

}

デモ

以下のデモ コードは、次のことができることを示しています。

package forum11333165;

import java.io.StringReader;
import javax.xml.bind.*;

public class Demo {

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

        StringReader xml = new StringReader("<Address><Name>Test</Name></Address>");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Address address = (Address) unmarshaller.unmarshal(xml);

        System.out.println(address.getPostalAddress().getState());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(address, System.out);
    }

}

出力

以下は、デモ コードを実行した結果の出力です。ご覧のとおりnull、探していた値が得られましたが、出力には余分なPostalAddressメソッドが含まれています。

null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Address>
    <Name>Test</Name>
    <PostalAddress/>
</Address>

オプション #2 - プロパティが Null の場合、新しいインスタンスを返す (非推奨)

住所

package forum11333165;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Address")
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {

    @XmlElement(name="Name")
    private String name;

    @XmlElement(name="PostalAddress")
    private PostalAddress postalAddress;

    public String getName() {
        return name;
    }

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

    public PostalAddress getPostalAddress() {
        if(null == postalAddress) {
            return new PostalAddress();
        }
        return postalAddress;
    }

    public void setPostalAddress(PostalAddress postalAddress) {
        this.postalAddress = postalAddress;
    }

}

出力

前のオプションと同じデモ コードを使用して、新しい出力を生成できます。PostalAddressget は引き続き機能し、追加のメソッドは取得されません。マイナス面は、設定したと思っていた状態がキャプチャされていないことです。

null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Address>
    <Name>Test</Name>
</Address>  

オプション #3 - Get On It を呼び出す前に値が Null でないことを確認する

このオプションは少し手間がかかりますが、最終的にはアプリケーションの保守が容易になります。

于 2012-07-04T21:05:05.613 に答える