TL;博士
您可以做一个虚拟编组并利用 JAXB 验证机制,而不是javax.xml.validation
直接使用这些机制。
杠杆Marshaller.Listener
& ValidationEventHandler
(商品验证器)
对于这个例子,我们将利用各个方面Marshaller.Listener
来ValidationEventHandler
完成用例。
Marshal.Listener
- 这将为每个正在编组的对象调用。我们可以使用它来缓存Order
我们可能需要从中删除实例的实例Commodity
。
ValidationEventHandler
这将使我们能够访问在marshal
操作期间验证出现的每个问题。对于每个问题,它将传递一个ValidationEvent
. 这ValidationEvent
将包含一个ValidationEventLocator
我们可以从中获取有问题的对象被编组的对象。
import javax.xml.bind.*;
public class CommodityValidator extends Marshaller.Listener implements ValidationEventHandler {
private Order order;
@Override
public void beforeMarshal(Object source) {
if(source instanceof Order) {
// If we are marshalling an Order Store It
order = (Order) source;
}
}
@Override
public boolean handleEvent(ValidationEvent event) {
if(event.getLocator().getObject() instanceof Commodity) {
// If the Error was Caused by a Commodity Object Remove it from the Order
order.setCommodity(null);
return true;
}
return false;
}
}
演示代码
可以运行以下代码来证明一切正常。
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.*;
import org.xml.sax.helpers.DefaultHandler;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Orders.class);
// STEP 1 - Build the Object Model
Commodity commodity1 = new Commodity();
commodity1.setId("1");
Order order1 = new Order();
order1.setCommodity(commodity1);
Commodity commodityInvalid = new Commodity();
commodityInvalid.setId("INVALID");
Order order2 = new Order();
order2.setCommodity(commodityInvalid);
Commodity commodity3 = new Commodity();
commodity3.setId("3");
Order order3 = new Order();
order3.setCommodity(commodity3);
Orders orders = new Orders();
orders.getOrderList().add(order1);
orders.getOrderList().add(order2);
orders.getOrderList().add(order3);
// STEP 2 - Check that all the Commodities are Set
System.out.println("\nCommodities - Before Validation");
for(Order order : orders.getOrderList()) {
System.out.println(order.getCommodity());
}
// STEP 3 - Create the XML Schema
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("src/forum16953248/schema.xsd"));
// STEP 4 - Perform Validation with the Marshal Operation
Marshaller marshaller = jc.createMarshaller();
// STEP 4a - Set the Schema on the Marshaller
marshaller.setSchema(schema);
// STEP 4b - Set the CommodityValidator as the Listener and EventHandler
CommodityValidator commodityValidator = new CommodityValidator();
marshaller.setListener(commodityValidator);
marshaller.setEventHandler(commodityValidator);
// STEP 4c - Marshal to Anything
marshaller.marshal(orders, new DefaultHandler());
// STEP 5 - Check that the Invalid Commodity was Removed
System.out.println("\nCommodities - After Validation");
for(Order order : orders.getOrderList()) {
System.out.println(order.getCommodity());
}
}
}
输出
下面是运行演示代码的输出。节点在封送操作之后如何移除无效商品。
Commodities - Before Validation
forum16953248.Commodity@3bb505fe
forum16953248.Commodity@699c8551
forum16953248.Commodity@22f4bf02
Commodities - After Validation
forum16953248.Commodity@3bb505fe
null
forum16953248.Commodity@22f4bf02
XML 架构 (schema.xsd)
下面是用于此示例的 XML 模式。
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="orders">
<complexType>
<sequence>
<element name="order" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="commodity">
<complexType>
<attribute name="id" type="int"/>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
JAVA模型
下面是我在这个例子中使用的对象模型。
订单
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Orders {
private List<Order> orderList = new ArrayList<Order>();
@XmlElement(name="order")
public List<Order> getOrderList() {
return orderList;
}
}
命令
public class Order {
private Commodity commodity;
public Commodity getCommodity() {
return commodity;
}
public void setCommodity(Commodity commodity) {
this.commodity = commodity;
}
}
商品
import javax.xml.bind.annotation.*;
public class Commodity {
private String id;
@XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}