3

我有一个类 Person 具有属性名称和地址。我在 XML 中显示它。从 XML 解组时,可以分别获取名称和地址的行号。我尝试使用定位器。但它不提供单独的行号。

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;

}

字符串适配器

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;

}

输入.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 回答