JAXB过滤了解析 [英] JAXB filtered parsing

查看:107
本文介绍了JAXB过滤了解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JAXB来解析基于GWT的应用程序中的XML文件。 XML看起来像这样(简化示例):

I'm using JAXB to parse an XML file in my GWT based application. The XML looks like this (a simplified example):

<addressbook>

    <company name="abc">
        <contact>
            <name>...</name>
            <address>...</address>
        </contact>

        <contact>
            <name>...</name>
            <address>...</address>
        </contact>

        <contact>
            <name>...</name>
            <address>...</address>
        </contact>
        ... 
        ... 
    </company>

    <company name="def">
        <contact>
            <name>...</name>
            <address>...</address>
        </contact>
        ...
        ...
    </company>

    ...
    ...

</addressbook>

我已经定义了如下所示的类:

I've defined the classes as shown below:

@XmlRootElement(name="addressbook")
public class Addressbook implements Serializable {

    private ArrayList<Company> companyList = new ArrayList<Company>();

    public Addressbook() {            
    }

    @XmlElement(name = "company")
    public ArrayList<Company> getCompanyList() {
        return companyList;
    }


}

=============================

@XmlRootElement(name="company")
public class Company implements Serializable {

    private String name;

    private ArrayList<Contact> contactList = new ArrayList<Contact>();

    public Company() {      
    }

    @XmlAttribute
    public String getName() {
        return name;
    }

    @XmlElement(name = "contact")
    public ArrayList<Contact> getContactList() {
        return contactList;
    }

    ...
    ...
}

=============================

@XmlRootElement(name="contact")
public class Contact implements Serializable
{
    private String name;
    private String address;

    public Contact() {
    }

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

    @XmlElement
    public String getAddress ()
    {
        return address;
    }

    ...
    ...
}

这是代码:

try {
    JAXBContext jc = JAXBContext.newInstance(Addressbook.class);
    Unmarshaller um = jc.createUnmarshaller();
    addressbook = (Addressbook) um.unmarshal(new FileReader("ds/addressbook.xml"));        
} catch (JAXBException e) {
    e.printStackTrace();
}

我需要根据公司名称获取联系人列表。例如,获取公司abc的所有联系人。我可以解析整个XML文件,然后手动过滤记录。但是如果输入文件很大,那么解析我需要的东西可能会更有效。那么是否可以预先指定一个标准并仅解析特定记录?

I need to get the list of contacts based on the company name. For example, get all contacts for company "abc". I can parse the entire XML file and then manually filter the records. But if the input file is big, it might be more efficient to parse only what I need. So is it possible to specify a criterion upfront and parse only specific records?

谢谢。

推荐答案

您可以在 EclipseLink JAXB(MOXy )来处理这种情况(我是MOXy技术主管):

You could use the @XmlPath extension in EclipseLink JAXB (MOXy) to handle this case (I'm the MOXy tech lead):

@XmlRootElement(name="addressbook")
public class Addressbook implements Serializable {

    private ArrayList<Company> companyList = new ArrayList<Company>();

    public Addressbook() {            
    }

    @XmlPath("company[@name='abc']")
    public ArrayList<Company> getCompanyList() {
        return companyList;
    }


}

更多信息:

  • http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html

更新 - 使用StreamFilter

以下示例演示了如何在此用例中使用StreamFilter:

The example below demonstrates how a StreamFilter could be leveraged for this use case:

import java.io.FileInputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Demo {

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

        XMLInputFactory xif = XMLInputFactory.newFactory();
        FileInputStream xmlStream = new FileInputStream("input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(xmlStream);
        xsr = xif.createFilteredReader(xsr, new CompanyFilter());

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Addressbook addressbook = (Addressbook) unmarshaller.unmarshal(xsr);

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

StreamFilter的实现如下:

The implementation of the StreamFilter is as follows:

import javax.xml.stream.StreamFilter;
import javax.xml.stream.XMLStreamReader;

public class CompanyFilter implements StreamFilter {

    private boolean accept = true;

    public boolean accept(XMLStreamReader reader) {
        if(reader.isStartElement() && "company".equals(reader.getLocalName())) {
            accept = "abc".equals(reader.getAttributeValue(null, "name"));
        } else if(reader.isEndElement()) {
            boolean returnValue = accept;
            accept = true;
            return returnValue;
        }
        return accept;
    }

}

这篇关于JAXB过滤了解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆