gpt4 book ai didi

java - 使用 jaxb 从复杂对象验证嵌套对象

转载 作者:行者123 更新时间:2023-11-30 09:21:31 27 4
gpt4 key购买 nike

我有一个对象的 xml 表示形式OrderList (has list of) 订单,每个订单都有一个商品列表。

我想验证我的商品,如果无效,我想将它们从订单中移除。如果所有商品都无效,那么我会从订单列表中删除该订单。

我已经能够验证订单列表

JAXBContext jaxbContext = JAXBContext.newInstance("com.jaxb");
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File(XSD));
JAXBSource source = new JAXBSource(jaxbContext, orderList);
Validator validator = schema.newValidator();
DataFeedErrorHandler handler = new DataFeedErrorHandler();
validator.setErrorHandler(handler);
validator.validate(source);

我找不到验证商品的方法。

有点像

for(Order order: orderList){
for(Commodity commodity: order.getCommodity()){
if(!isCommodityValid(commodity)){
// mark for removal
}
}
}

如有任何帮助,我们将不胜感激。

最佳答案

长话短说

您可以执行一个虚拟编码并利用 JAXB 验证机制,而不是直接使用 javax.xml.validation 机制。

利用 Marshaller.ListenerValidationEventHandler (CommodityValidator)

对于此示例,我们将利用 Marshaller.ListenerValidationEventHandler 的各个方面来完成用例。

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

}

关于java - 使用 jaxb 从复杂对象验证嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16953248/

27 4 0
文章推荐: javascript - 如何在每个给定的时间间隔连续移动