3

名前とアドレスの属性を持つPersonクラスがあります。XMLで表示します。XMLからアンマーシャリングしている間、名前とアドレスの行番号を別々に取得することが可能になります。Locatorを使ってみました。ただし、個々の行番号は提供されません。

4

2 に答える 2

3

EclipseLink JAXB(MOXy)とJAXBリファレンス実装には、それぞれこのユースケースをサポートするための独自の@XmlLocationアノテーションがあります。これにより、オブジェクトに対応するXML要素上の場所をのインスタンスとして保存できますorg.xml.sax.Locator。私はMOXyのリーダーなので、MOXyの使用方法を説明します。

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlJavaTypeAdapter(value=StringAdapter.class)
    String name;

    Address address;

    @XmlLocation
    Locator locator;

}

住所

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;

public class Address {

    @XmlJavaTypeAdapter(value=StringAdapter.class)
    private String street;

    @XmlLocation
    Locator locator;

}

StringAdapter

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;

public class StringAdapter extends XmlAdapter<StringAdapter.AdaptedString, String> {

    public static class AdaptedString {

        @XmlValue
        public String value;

        @XmlLocation
        @XmlTransient
        Locator locator;

    }

    @Override
    public String unmarshal(AdaptedString v) throws Exception {
        System.out.println(v.value + " " + v.locator.getLineNumber());
        return v.value;
    }

    @Override
    public AdaptedString marshal(String v) throws Exception {
        AdaptedString adaptedString = new AdaptedString();
        adaptedString.value = v;
        return adaptedString;
    }

}

jaxb.properties

MOXyをJAXBプロバイダーとして指定するには、jaxb.propertiesドメインモデルと同じパッケージで呼び出されるファイルを次のエントリに含める必要があります。

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

デモ

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

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14455596/input.xml");
        Person person = (Person) unmarshaller.unmarshal(xml);

        System.out.println("Person:  " + person.locator.getLineNumber());
        System.out.println("Address:  " + person.address.locator.getLineNumber());
    }

}

出力

Jane Doe 3
1 A Street 5
Person:  2
Address:  4
于 2013-01-22T10:55:19.100 に答える
2

StAXStreamReaderDelegateを活用して、次のようなことを行うことができます。

デモ

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

public class Demo {

    public static void main(String[] args) throws Exception {

        JAXBContext jc = JAXBContext.newInstance(Person.class);

        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource source = new StreamSource("src/forum14455596/input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(source);
        xsr = new StreamReaderDelegate(xsr) {

            @Override
            public String getLocalName() {
                String localName = super.getLocalName();
                if(isStartElement()) {
                    System.out.println(localName + " " + this.getLocation().getLineNumber());
                }
                return localName;
            }

        };

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.unmarshal(xsr);
    }

}

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    private String name;
    private String address;

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<person>
    <name>Jane Doe</name>
    <address>1 A Street</address>
</person>

出力

person 2
name 3
address 4
于 2013-01-22T10:21:56.417 に答える