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

s2j5cfk0  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(482)

我有一个对象的xml表示,比如orderlist(has list of)orders,每个order都有一个商品列表。
我想验证我的商品,如果无效,我想把他们从订单上删除。如果所有商品都是无效的,那么我将从订单列表中删除订单。
我已经能够验证订单列表

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

任何帮助都将不胜感激。

2w3kk1z5

2w3kk1z51#

热释光;博士
您可以执行虚拟封送并利用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;
    }

}

相关问题