如何使用Java中的XSD验证XML文件?我们事先不知道架构.我希望能够获得schemaLocation,下载XSD,缓存它,然后执行实际验证.
问题是,使用javax.xml.parsers.DocumentBuilder / DocumentBuilderFactory类,我似乎无法提前获得schemaLocation.这是什么诀窍?我应该研究哪些课程?
也许我可以使用更合适的API?整个问题是我们需要动态验证,而不必(必须)在本地使用XSD.
如何获得XSD文件中定义的schemaLocation的URL?
我知道你可以设置功能/属性,但这是另一回事.我需要先从XSD获取schemaLocation.
请指教!
最佳答案
鉴于您使用的是Xerces(或JDK默认值),您是否尝试在工厂中将此功能设置为true:http://apache.org/xml/features/validation/schema.您可以使用其他有关模式的功能:http://xerces.apache.org/xerces2-j/features.html
原文链接:/java/438002.html更新2(用于缓存):
实现org.w3c.dom.ls.LSResourceResolver并使用setResourceResolver方法在SchemaFactory上设置它.此解析程序可以从缓存中获取模式,也可以从位置引用的任何位置获取模式.
更新3:
LSResourceresolver示例(我认为这将是一个很好的起点):
/**
* Resolves resources from a base URL
*/
public class URLBasedResourceResolver implements LSResourceResolver {
private static final Logger log = LoggerFactory
.getLogger(URLBasedResourceResolver.class);
private final URI base;
private final MapSyntaxException {
super();
this.base = base.toURI();
this.nsmap = nsmap;
}
@Override
public LSInput resolveResource(String type,String namespaceURI,String publicId,String systemId,String baseURI) {
if (log.isDebugEnabled()) {
String msg = String
.format("Resolve: type=%s,ns=%s,publicId=%s,systemId=%s,baseUri=%s.",type,namespaceURI,publicId,systemId,baseURI);
log.debug(msg);
}
if (type.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
if (namespaceURI != null) {
try {
URI ns = new URI(namespaceURI);
if (nsmap.containsKey(ns))
return new MyLSInput(base.resolve(nsmap.get(ns)));
} catch (URISyntaxException e) {
// ok
}
}
}
return null;
}
}
MyLSInput的实现真的很无聊:
class MyLSInput implements LSInput {
private final URI url;
public MyLSInput(URI url) {
super();
this.url = url;
}
@Override
public Reader getCharacterStream() {
return null;
}
@Override
public void setCharacterStream(Reader characterStream) {
}
@Override
public InputStream getByteStream() {
return null;
}
@Override
public void setByteStream(InputStream byteStream) {
}
@Override
public String getStringData() {
return null;
}
@Override
public void setStringData(String stringData) {
}
@Override
public String getSystemId() {
return url.toASCIIString();
}
@Override
public void setSystemId(String systemId) {
}
@Override
public String getPublicId() {
return null;
}
@Override
public void setPublicId(String publicId) {
}
@Override
public String getBaseURI() {
return null;
}
@Override
public void setBaseURI(String baseURI) {
}
@Override
public String getEncoding() {
return null;
}
@Override
public void setEncoding(String encoding) {
}
@Override
public boolean getCertifiedText() {
return false;
}
@Override
public void setCertifiedText(boolean certifiedText) {
}
}