从java.io.Reader读取xml而不是提供xml文件的路径时,saxreader验证失败

时间:2016-09-08 14:29:18

标签: java xml xml-validation

我有简单的xml文件contacts.xml,位于实际文件夹的子文件夹 xml-files 中。

<contacts xsi:noNamespaceSchemaLocation="contacts.xsd"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <contact> 
        <firstname>AAA</firstname> 
        <lastname>BBB</lastname>
    </contact> 
</contacts>

架构文件也位于子文件夹 xml-files

解析文件的代码:

  SAXParserFactory factory = SAXParserFactory.newInstance();
  factory.setValidating(true);

  SAXParser parser = factory.newSAXParser();                              
  parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

  SAXReader reader = new SAXReader(parser.getXMLReader());
  reader.setValidation(true);
  reader.read("xml-files/contacts.xml");

我想使用SAXReader的read方法,它将java.io.Reader作为参数,如下所示

reader.read(new FileReader("xml-files/contacts.xml"));

但我得到例外

org.dom4j.DocumentException:文档第2行出错:cvc-elt.1:无法找到元素'contacts'的声明。嵌套异常:cvc-elt.1:找不到元素'contacts'的声明。

使用自定义实体解析器显示,在第一种情况下,xsd文件是从路径文件中加载的:/// e:/devel/xsd/xml-files/contacts.xsd,在第二种情况下是文件:/// e:/ devel的/ XSD / contacts.xsd。

有没有办法将SAXReader设置为xsd文件所在的文件夹?

2 个答案:

答案 0 :(得分:0)

未经测试,但从我上面的评论来看,这就是我的想法:

Platform.where(url:urls).eager_load(:campaign_platforms).where.not('campaign_platforms.campaign_id = ?', campaign.id)

答案 1 :(得分:0)

Java: How to prevent 'systemId' in EntityResolver#resolveEntity(String publicId, String systemId) from being absolutized to current working directory的启发,我使用了自己的EntityResolver2实现

private static class EntityResolver2Impl implements EntityResolver2 {
    private File xmlFile;
    public EntityResolver2Impl(File xmlFile) {
        this.xmlFile = xmlFile;
    }

    @Override
    public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException {
        return null;
    }

    @Override
    public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException {
        File entityPath = new File(xmlFile.getParent(), systemId);
        return new InputSource(new FileReader(entityPath));
    }

    @Override
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        return null;
    }
}

调用代码看起来像这样

 File xmlFile = new File("xml-files/contacts.xml");
 SAXParserFactory factory = SAXParserFactory.newInstance();

 factory.setValidating(true);

 SAXParser parser = factory.newSAXParser();                              
 parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

 SAXReader reader = new SAXReader(parser.getXMLReader());
 reader.setEntityResolver(new EntityResolver2Impl(xmlFile));
 reader.setValidation(true);
 reader.read(new FileReader(xmlFile));

此代码还可以处理xsd的路径包含通向父文件夹(../ ..)等的相对路径的情况。