2

異なる名前空間に属する MOXy とクラスを使用していますが、MOXy は常に間違った名前空間を参照先のオブジェクトに追加します。この単純な例が期待どおりに機能しないのはなぜですか?

AtomLink.java:

package org.atom;

@XmlAccessorType(XmlAccessType.NONE)
public class AtomLink {

    @XmlAttribute
    protected String rel;
    @XmlAttribute(required = true)
    @XmlSchemaType(name = "anyURI")
    protected String href;

    public AtomLink() {
    }

    public AtomLink(String rel, String href) {
        this.rel = rel;
        this.href = href;
    }

}

Person.java

package org.example;

import org.atom.AtomLink;

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.NONE)
public class Person {

    @XmlElement
    protected String name;
    @XmlElement
    protected AtomLink link;

    public Person() {
    }

    public Person(String name, AtomLink link) {
        this.name = name;
        this.link = link;
    }

}

パッケージ情報.java

@XmlSchema(namespace = "http://www.w3.org/2005/Atom", xmlns={
    @XmlNs(namespaceURI = "http://www.w3.org/2005/Atom", prefix = "atom")}, elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.QUALIFIED) 
package org.atom;

パッケージ情報.java

@XmlSchema(namespace = "http://www.test.org", xmlns={
    @XmlNs(namespaceURI = "http://www.test.org", prefix = "test")}, elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED) 
package org.example;

テストコード:

Person person = new Person("Test", new AtomLink("self", "http://www.test.org/person/Test"));
try {
    JAXBContext context = JAXBContextFactory.createContext(new Class[] { Person.class }, null);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(person, System.out);
} catch (JAXBException e) {
    e.printStackTrace();
}

結果:

<?xml version="1.0" encoding="UTF-8"?>
<test:person xmlns:atom="http://www.w3.org/2005/Atom" xmlns:test="http://www.test.org">
    <test:name>Test</test:name>
    <test:link atom:rel="self" atom:href="http://www.test.org/person/Test"/>
</test:person>

しかし、私は期待しています:

...
    <atom:link atom:rel="self" atom:href="http://www.test.org/person/Test"/>
...

AtomLink クラスが別の名前空間に属していることを MOXy が認識しないのはなぜですか? ご覧のとおり、要素の名前空間だけが間違っていますが、その属性は正しい名前空間に割り当てられています。

アップデート

提案どおり、次の変更を行いました。クラスは次のようになります。

AtomLink.java

@XmlRootElement(name = "link")
@XmlAccessorType(XmlAccessType.NONE)
public class AtomLink {

    @XmlAttribute
    protected String rel;
    @XmlAttribute(required = true)
    @XmlSchemaType(name = "anyURI")
    protected String href;

    public AtomLink() {
    }

}

Person.java:

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.NONE)
public class Person {

    @XmlElement
    private String name;
    @XmlElementRef
    private AtomLink link;

    public Person() {
    }

    public Person(String name, AtomLink link) {
        this.name = name;
        this.link = link;
    }

}

結果は無効な XML ドキュメントで、n0 が link 要素の targetNamespace として定義されていますが、その属性は私のアトム プレフィックスに割り当てられています。

<?xml version="1.0" encoding="UTF-8"?>
<test:person xmlns:test="http://www.test.org" xmlns:ns0="http://www.w3.org/2005/Atom>
    <test:name>Test</test:name>
    <ns0:link atom:rel="self" atom:href="http://www.test.org/person/Test"/>
</test:person>

「 http://www.test.org 」名前空間を atom-entry で拡張することは解決策ではありません。XML ドキュメントに atom 要素が存在しない場合でも、常に名前空間宣言になるからです。

Update2

Java 内部 JAXB 実装を使用すると、すべてが期待どおりに機能します... MOXy 実装にエラーがあるはずです。

4

2 に答える 2

1

これが JAXB の仕組みです。ローカル要素の名前空間 (その名前と同じなので当然のことです) は、その@XmlElement注釈の属性によって指定されます。

AtomLinkではなくでこれらを決定したい場合Person(名前空間と名前の両方、それらは一緒に使用されるため)、それを作成してPerson@XmlRootElementで使用する必要があります。@XmlElementRef

一緒にいたいなら@XmlElement

@XmlElement(namespace="http://www.w3.org/2005/Atom")
private AtomLink link;

行く方法です。

于 2013-02-12T08:29:02.683 に答える
1

あなたが経験していたのは、EclipseLink 2.4.2 および 2.5.0 ストリームで修正された MOXyのバグでした。2013 年 2 月 13 日現在、ナイトリー ビルドは次の場所からダウンロードできます。

正しいマッピングに関しては、Michał Politowski による回答を参照してください。

于 2013-02-12T21:04:48.263 に答える