JAXB检查xml是否对声明的xsd有效

时间:2014-01-23 19:04:20

标签: java xml jaxb xsd

在调用Unmarshaller的unmarshal方法之前,我需要知道xml是否有效。

现在我这样做:

JAXBContext jaxbContext = JAXBContext.newInstance("package");

final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final File xsdFile = new File("pathtoxsd/file.xsd");
final Schema schema = schemaFactory.newSchema(xsdFile);

unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new ValidationEventHandler() {
    @Override
    public boolean handleEvent(ValidationEvent arg0)
    {
            return false;
    }
});

final File xmlFile = new File("pathtoxml/fileName.xml");

final Object unmarshalled = unmarshaller.unmarshal(xmlFile);

但我不想被迫知道xsd在哪里。 xsd路径应仅由其内部的xml声明,并且编组器应遵循xml声明的路径。

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

  1. 使用StAX解析器解析XML文档。
  2. 前进到根元素。
  3. 抓取schemaLocation属性(您可能还需要处理noNamespaceSchemaLocation属性)。
  4. 从该值抓取XSD的路径(空格后的部分)。
  5. 根据该值创建Schema
  6. Schema
  7. 上设置Unmarshaller
    import javax.xml.XMLConstants;
    import javax.xml.bind.*;
    import javax.xml.stream.*;
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            XMLInputFactory xif = XMLInputFactory.newFactory();
            StreamSource xml = new StreamSource("src/forum21317146/input.xml");
            XMLStreamReader xsr = xif.createXMLStreamReader(xml);
            xsr.next();
    
            JAXBContext jc = JAXBContext.newInstance(Foo.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
    
            String schemaLocation = xsr.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation");
            if(null != schemaLocation) {
                String xsd = schemaLocation.substring(schemaLocation.lastIndexOf(' ') + 1);
                SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                Schema schema = schemaFactory.newSchema(new StreamSource(xsd));
                unmarshaller.setSchema(schema);
            }
    
            unmarshaller.unmarshal(xsr);
    
        }
    
    }