1

以下は、私のクラスと OXM のマッピングです。phoneType を phone の子要素にしたい場合、以下の例外が発生する理由がわかりません

public class PhoneNumber
{
    public enum PhoneType
    {
        Cell, Home
    };

    private PhoneType phoneType;

    private String type;

    private String number;

    public String getType()
    {
        return type;
    }

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

    public String getNumber()
    {
        return number;
    }

    public void setNumber(final String number)
    {
        this.number = number;
    }

    public void setPhoneType(final PhoneType phoneType)
    {
        this.phoneType = phoneType;
    }

    public PhoneType getPhoneType()
    {
        return phoneType;
    }

}

OXM

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
   version="2.4"  package-name="blog.bindingfile"  xml-mapping-metadata-complete="true">
   <xml-schema namespace="http://www.example.com/customer" element-form-default="QUALIFIED" />
   <java-types>
      <java-type name="Customer">
         <xml-root-element name="customer"/>
         <xml-type prop-order="lastName firstName address phoneNumbers" />
         <java-attributes>
            <xml-element java-attribute="firstName" name="first-name" />
            <xml-element java-attribute="lastName" name="last-name" />
            <xml-element java-attribute="phoneNumbers" name="phone-number" />
         </java-attributes>
      </java-type>
      <java-type name="BaseCustomer" xml-transient="true">
      <xml-root-element/>
      </java-type>
      <java-type name="PhoneNumber">
         <java-attributes>
            <xml-attribute java-attribute="type" />
            <xml-value java-attribute="number" />
            <xml-element java-attribute="phoneType" name="phone-type"/>
         </java-attributes>
      </java-type>
   </java-types>
</xml-bindings>

例外

Caused by: Exception [EclipseLink-50010] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The property or field phoneType must be an attribute because another field or property is annotated with XmlValue.
    at org.eclipse.persistence.exceptions.JAXBException.propertyOrFieldShouldBeAnAttribute(JAXBException.java:246)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.finalizeProperties(AnnotationsProcessor.java:1011)
    at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:412)
    at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:102)
    at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:768)
    ... 11 more
4

1 に答える 1

1

アップデート

例外が発生する理由を完全に理解するために、フォーマットされた XML フラグメントを見ていきます。問題は、@XmlValue マッピングが対応するテキスト フラグメント (最初、2 番目、どちらでもない?) に帰着します。

<phone-number type="TYPE">
    <phone-type>Cell</phone-type>
</phone-number>

次のドキュメントには混合コンテンツが含まれているため、JAXB ではこれを明示的に呼び出す必要があります。通常、混合を使用し@XmlAnyElementて、すべての要素とテキストのリストを取得し、順序を維持できるようにします。

<phone-number type="TYPE">
    555-1111
    <phone-type>Cell</phone-type>
</phone-number>

OXM ファイルの次の理由により、例外が発生しています。

  <java-type name="PhoneNumber">
     <java-attributes>
        <xml-attribute java-attribute="type" />
        <xml-value java-attribute="number" />
        <xml-element java-attribute="phoneType" name="phone-type"/>
     </java-attributes>
  </java-type>

@XmlElement例外として、クラス内の別のフィールド/プロパティがマップされている場合、フィールド/プロパティをマップすることはできません@XmlValue

代わりに必要なこと

要素を混合コンテンツにマップしようとしています。以下のマッピングファイルを使用してこれを行うことができます。

<java-type name="PhoneNumber">
    <java-attributes>
        <xml-attribute java-attribute="type" />
        <xml-any-element java-attribute="number" xml-mixed="true"/>
        <xml-element java-attribute="phoneType" name="phone-type" />
    </java-attributes>
</java-type>

完全な例

oxm.xml

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum11988974">
    <java-types>
        <java-type name="PhoneNumber">
            <xml-root-element name="phone-number"/>
            <java-attributes>
                <xml-attribute java-attribute="type" />
                <xml-any-element java-attribute="number" xml-mixed="true"/>
                <xml-element java-attribute="phoneType" name="phone-type" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

デモ

package forum11988974;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum11988974/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {PhoneNumber.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum11988974/input.xml");
        PhoneNumber phoneNumber = (PhoneNumber) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(phoneNumber, System.out);
    }

}

input.xml/出力

<?xml version="1.0" encoding="UTF-8"?>
<phone-number type="TYPE">555-1111<phone-type>Cell</phone-type></phone-number>
于 2012-08-16T14:52:05.080 に答える