[英]saxreader validation fails when reading xml from java.io.Reader instead of providing path to xml file
我在實際文件夾的子文件夾xml文件中有一個簡單的xml文件contacts.xml。
<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:找不到元素“聯系人”的聲明。
使用定制的entityresolver顯示,在第一種情況下,xsd文件是從路徑file:/// e:/devel/xsd/xml-files/contacts.xsd加載的,在第二種情況下是從文件:/// e:/ devel / xsd加載的/contacts.xsd。
有什么方法可以將xsd文件所在的文件夾設置為SAXReader?
未經測試,但是從我上面的評論中,這就是我的想法:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
SchemaFactory schemafactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source[] sources = new Source[] {
new StreamSource(new File("path/to/schema1.xsd")),
new StreamSource(new File("path/to/schema2.xsd")),
new StreamSource(new File("path/to/schema3.xsd")),
new StreamSource(new File("path/to/schema4.xsd")),
};
Schema sc = schemafactory.newSchema(sources);
factory.setSchema(sc);
SAXParser parser = factory.newSAXParser();
parser.parse(file, handler);
受Java啟發:如何防止EntityResolver#resolveEntity(String publicId,String systemId)中的'systemId'絕對到當前工作目錄,我使用了自己的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的路徑包含指向父文件夾(../ ..)等的相對路徑的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.