gpt4 book ai didi

java - JAXB 过滤解析

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:16:42 26 4
gpt4 key购买 nike

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

<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>

我定义了如下所示的类:

@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 文件,然后手动过滤记录。但是如果输入文件很大,只解析我需要的可能会更有效。那么是否可以预先指定一个标准并仅解析特定记录?

谢谢。

最佳答案

您可以在 EclipseLink JAXB (MOXy 中使用 @XmlPath 扩展名) 来处理这种情况(我是 MOXy 技术主管):

@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;
}


}

更多信息:


更新 - 使用 StreamFilter

下面的示例演示了如何将 StreamFilter 用于此用例:

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的实现如下:

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;
}

}

关于java - JAXB 过滤解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5949265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com