10

私のXSD構造は以下のようなものです:-

<element name="XYZDate" maxOccurs="1" minOccurs="1" nillable="true" type="date"/>

このフィールドにnull値を設定すると許可されますが、XML生成時にJAXBマーシャリングから次の出力が生成されます。

<XYZDate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

結果として、私は出力が必要<XYZDate/>です。つまり、スキーマやその他の属性は必要ありません。
私はを使用してこれを取り除きますが、それは単一行でXMLStreamWriter完全なものを生成します。XML整形式のフォーマットが必要ですXMLIndentingXMLStreamWriter自分のバージョンを使用する必要がある場合は、Javaそれをサポートしておらず、変更または変更するJavaコンテナを制御できません。

XML適切にフォーマットされたものを形成するための解決策を提案してください。

4

4 に答える 4

15

注 1: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。


注 #2: 表示されている出力は、JAXB でマップしたものと一致します。詳細については、次を参照してください。


NULL を空の要素として表現する

null を空の要素として表現したい場合は、いくつかのオプションがあります。

オプション 1 - 標準の JAXB API を使用する

日付アダプター

を使用しXmlAdapterて、 のインスタンスDateを XML にマーシャリングする方法を変更できます。日付を、1 つのプロパティがマッピングされたクラスのインスタンスに変換します@XmlValue( http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.htmlを参照)。JAXB RI はXmlAdapternull 値のメカニズムを呼び出さないため、MOXy などの JAXB impl を使用する必要があります。

package forum11743306;

import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateAdapter extends XmlAdapter<DateAdapter.AdaptedDate, XMLGregorianCalendar>{

    @Override
    public AdaptedDate marshal(XMLGregorianCalendar date) throws Exception {
        AdaptedDate adaptedDate = new AdaptedDate();
        adaptedDate.value = date;
        return adaptedDate;
    }

    @Override
    public XMLGregorianCalendar unmarshal(AdaptedDate adaptedDate) throws Exception {
        return adaptedDate.value;
    }

    public static class AdaptedDate {
        @XmlValue
        public XMLGregorianCalendar value;
    }

}

は注釈XmlAdapterを使用して参照されます。@XmlJavaTypeAdapter

package forum11743306;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlRootElement
public class Root {

    private XMLGregorianCalendar xyzDate;

    @XmlElement(name = "XYZDate", required=true, nillable = true)
    @XmlJavaTypeAdapter(DateAdapter.class)
    public XMLGregorianCalendar getXyzDate() {
        return xyzDate;
    }

    public void setXyzDate(XMLGregorianCalendar xyzDate) {
        this.xyzDate = xyzDate;
    }

}

オプション #2 - MOXy の @XmlNullPolicy 拡張を使用する

MOXy は、@XmlNullPolicynull を表現する方法にある程度の柔軟性を与える拡張機能を提供します。

package forum11743306;

import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.persistence.oxm.annotations.*;

@XmlRootElement
public class Root {

    private XMLGregorianCalendar xyzDate;

    @XmlElement(name = "XYZDate", required=true, nillable = true)
    @XmlNullPolicy(emptyNodeRepresentsNull = true, nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE)
    public XMLGregorianCalendar getXyzDate() {
        return xyzDate;
    }

    public void setXyzDate(XMLGregorianCalendar xyzDate) {
        this.xyzDate = xyzDate;
    }

}

その他のファイル

次のファイルをいずれかのオプションと共に使用して、例を完成させることができます。

jaxb.properties

MOXy を JAXB プロバイダーとして指定するにはjaxb.properties、次のエントリを使用して、ドメイン モデルと同じパッケージで呼び出されるファイルを含める必要があります ( http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-asを参照)。 -your.html )。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

デモ

package forum11743306;

import javax.xml.bind.*;
import javax.xml.datatype.DatatypeFactory;

import org.eclipse.persistence.Version;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        System.out.println(Version.getVersion());
        System.out.println(jc.getClass());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Root root = new Root();
        root.setXyzDate(null);
        marshaller.marshal(root, System.out);

        root.setXyzDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2012-08-01"));
        marshaller.marshal(root, System.out);
    }

}

出力

2.4.0
class org.eclipse.persistence.jaxb.JAXBContext
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <XYZDate/>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <XYZDate>2012-08-01</XYZDate>
</root>
于 2012-07-31T20:42:15.500 に答える
4

nillableとminOccurs の XSD 要素属性nilを読み取る必要がありemptyますXML。iexsi:nil=trueに似てSQL NULLいますが、空の要素を持つことは、空の要素の存在を表します。:)
私はそれが混乱していることを知っています。

特定の問題を解決するには、JAXBシリアライゼーションを使用してそれを生成している場合は、How to instantiate a empty element with JAXB を読むことをお勧めします。質問自体は、空の要素を生成する方法を示しています。

于 2012-07-31T16:30:15.963 に答える
0

私はgbvbの答えに投票しました。

なぜこれが欲しいのか理解できませんが。

xmlns:xsiandを使用した空の要素xsi:nilは正しい方法です。

これらの属性がないと、reasonableパーサーは空の文字列を返しますeven if the element is self-closed

多くのプレーヤーのスコアの中で最高のスコアを意味する整数値をクライアントに与えたいとします。

計算できれば、正しい値を与えることができます。実際に得点した選手がまだいない場合は、記録が蓄積されていないことを意味するNULLorとして正しい値を使用する必要があります。nil

<highestScore among="128">98</highestScore>

128回中98回が最高得点と言えます。

<highestScore among="0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:nil="true"/>

スコアが記録されていないため、最高スコアはありません。

しかし

<highestScore/>

単純な自己閉鎖型の空の要素以外の意味はありません。

于 2012-08-03T12:51:51.227 に答える