3

JAXB を使用して xml を解析しています。

<countries>
    <Name language="en">Australia</Name>
    <Name language="se">Australien</Name>
</countries>

私が私のクラスの国で使用する場合

@XmlElement(name = "Name", required = true)
    protected List<Name> name;

すべてが機能します。ただし、language="en" の属性のみを取得したい

だから私は私の国クラスで持っています

protected String name

コレクションではありません。

たとえば、注釈を付けてこれを解決する良い方法はありますか?

4

1 に答える 1

4

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

以下に、このユース ケースを処理する 2 つの方法を示します。1 つ目はコードが少し増えますが、任意の JAXB 実装で実行できます。2 つ目はコードが少ないですが、EclipseLink JAXB (MOXy) を使用する必要があります。

オプション #1 - 任意の JAXB (JSR-222) の実装

デモ

フィルタリングされたストリームリーダーを使用して不要な要素を除外し、JAXB 実装でそれを非整列化することができます。

package forum11586106;

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    private static final String LANGUAGE_CODE = "en";

    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/forum11586106/input.xml"));
        xsr = xif.createFilteredReader(xsr, new StreamFilter() {

            private boolean isReading = true;

            @Override
            public boolean accept(XMLStreamReader reader) {
                if(reader.isStartElement() && "Name".equals(reader.getLocalName())) {
                    isReading = LANGUAGE_CODE.equals(reader.getAttributeValue("", "language"));
                    return isReading;
                } else if(reader.isEndElement() && !isReading) {
                    isReading = true;
                    return false;
                }

                return true;
            }});

        JAXBContext jc = JAXBContext.newInstance(Countries.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Countries countries = (Countries) unmarshaller.unmarshal(xsr);

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

}

package forum11586106;

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Countries {

    private String name;

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

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

}

入力.xml

このアプローチでは、言語属性は出力に含まれません。

<countries>
    <Name language="en">Australia</Name>
    <Name language="se">Australien</Name>
</countries>

出力

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<countries>
    <Name>Australia</Name>
</countries>

オプション #2 - ECLIPSELINK JAXB (MOXy)

MOXy の拡張機能を利用して、値を持つ属性を持つ要素@XmlPathにマップします( http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.htmlを参照)。Namelanguageen

package forum11586106;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
public class Countries {

    private String name;

    @XmlPath("Name[@language='en']/text()")
    public String getName() {
        return name;
    }

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

}

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

デモ

このアプローチでは、要素のフィルタリングが@XmlPathマッピングによって処理されるため、実行時の部分がはるかに単純になります。標準の JAXB ランタイム API のみが使用されていることに注意してください。

package forum11586106;

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

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum11586106/input.xml");
        Countries countries = (Countries) unmarshaller.unmarshal(xml);

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

}

入力.xml

<countries>
    <Name language="en">Australia</Name>
    <Name language="se">Australien</Name>
</countries>

出力

このアプローチでは、language属性が出力に含まれます。

<?xml version="1.0" encoding="UTF-8"?>
<countries>
   <Name language="en">Australia</Name>
</countries>
于 2012-07-20T20:35:00.213 に答える