【发布时间】:2014-06-26 08:13:33
【问题描述】:
我正在尝试将 @XmlAnyElement 与 DomHandler 一起使用来捕获特定字段中的未解析文本,例如 Blaise Doughan 的 this 示例。但是,当我尝试解析多个客户时,所有先前记录中的 bio 字段的内容会继续发送到我的 DomHandler!
这是我要解析的示例文档:
<?xml version="1.0" encoding="UTF-8"?>
<customers>
<customer>
<name>Jane Doe</name>
<bio>
<html>Jane's bio</html>
</bio>
</customer>
<customer>
<name>John Doe</name>
<bio>
<html>John's bio</html>
</bio>
</customer>
</customers>
但是输出是:
Name: Jane Doe
Bio: <html>Jane's bio</html>
Name: John Doe
Bio: <html>Jane's bio</html>
BioHandler(与previous example保持不变)
package blog.domhandler;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.DomHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class BioHandler implements DomHandler<String, StreamResult> {
private static final String BIO_START_TAG = "<bio>";
private static final String BIO_END_TAG = "</bio>";
private StringWriter xmlWriter = new StringWriter();
public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
return new StreamResult(xmlWriter);
}
public String getElement(StreamResult rt) {
String xml = rt.getWriter().toString();
int beginIndex = xml.indexOf(BIO_START_TAG) + BIO_START_TAG.length();
int endIndex = xml.indexOf(BIO_END_TAG);
return xml.substring(beginIndex, endIndex);
}
public Source marshal(String n, ValidationEventHandler errorHandler) {
try {
String xml = BIO_START_TAG + n.trim() + BIO_END_TAG;
StringReader xmlReader = new StringReader(xml);
return new StreamSource(xmlReader);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
客户(与previous example保持不变)
package blog.domhandler;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement
@XmlType(propOrder={"name", "bio"})
public class Customer {
private String name;
private String bio;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAnyElement(BioHandler.class)
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
}
客户
package blog.domhandler;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement
public class Customers {
private List<Customer> customers;
public List<Customer> getCustomer() {
return customers;
}
public void setCustomer(List<Customer> c) {
this.customers = c;
}
}
演示(驱动程序)
package blog.domhandler;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customers.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Customers customers = (Customers) unmarshaller.unmarshal(new File("src/blog/domhandler/input.xml"));
for( Customer customer: customers.getCustomer() ) {
System.out.println("Name: " + customer.getName());
System.out.println("Bio: " + customer.getBio());
}
}
}
当我在 BioHandler.getElement() 中放置断点时,我看到它第一次调用的 String xml 取值
<?xml version="1.0" encoding="UTF-8"?><bio><html>Jane's bio</html>
</bio>
第二次调用String xml时取值
<?xml version="1.0" encoding="UTF-8"?><bio><html>Jane's bio</html>
</bio><?xml version="1.0" encoding="UTF-8"?><bio><html>John's bio</html>
</bio>
是否有某种方法可以向解析器指示在每次调用 BioHandler.getElement() 后应该丢弃该内容?
【问题讨论】: