我想通过 Apache Commons Configuration2 加载 XML 配置,但也执行 XSD 验证。 XSD 不应链接到(可能不受信任的)配置文件中,而应来自应用程序。
我在 文档 和 StackOverflow 中都找不到匹配的示例。 一个与我的问题类似的问题有一个仅适用于 Apache Commons Configuration1 的答案,它的答案不适用于我。
如何加载和验证 XML 配置文件?
编辑:有人投票这个问题需要更多详细信息,所以在这里。
Apache Commons 配置文档中的 XSD 验证示例如下所示:
Parameters params = new Parameters();
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(params.xml()
.setFileName("myconfig.xml")
.setSchemaValidation(true));
// This will throw a ConfigurationException if the XML document does not
// conform to its Schema.
XMLConfiguration config = builder.getConfiguration();
此处的目的是根据 XSD 架构读取和验证 XML 配置文件 (
myconfig.xml
)。哪个模式?好吧,它需要在 XML 文档中引用。我想要的是我的应用程序强制使用哪个 XSD 模式进行验证。因此,我希望在代码中的某个时刻指定 XSD 架构并将其用于验证。这是我尝试过的:
File f = new File(xmlfile);
log.info("Reading {}", f.getAbsoluteFile());
URL url = getClass().getResource("/schema/configuration.xsd");
log.trace("loading XSD from {}", url);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(url.openStream());
Schema schema = factory.newSchema(schemaFile);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setSchema(schema);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
MyErrorHandler meh = new MyErrorHandler();
db.setErrorHandler(meh);
db.parse(f); // <<<=============== note this line
Parameters params = new Parameters();
params.xml()
.setSchemaValidation(true)
.setDocumentBuilder(db);
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>(XMLConfiguration.class)
.configure(params.xml().setFile(f));
config = builder.getConfiguration();
请注意
db.parse(f);
行:
MyErrorHandler
收到警告、错误和致命错误。这意味着虽然我的 DocumentBuilder 已配置为正确验证,但使用
params.setDocumentBuilder()
将其传递到配置生成器并没有帮助。
好吧,我花了一段时间才弄清楚为什么公共配置不进行验证。我传入的参数错误。这是我现在的工作:
File f = new File(xmlfile);
log.info("Reading {}", f.getAbsoluteFile());
URL url = getClass().getResource("/schema/configuration.xsd");
log.trace("loading XSD from {}", url);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(url.openStream());
Schema schema = factory.newSchema(schemaFile);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setSchema(schema);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
MyErrorHandler meh = new MyErrorHandler();
db.setErrorHandler(meh);
Parameters params = new Parameters();
FileBasedConfigurationBuilder<XMLConfiguration> builder = new FileBasedConfigurationBuilder<>(XMLConfiguration.class)
.configure(params.xml()
.setValidating(true)
.setSchemaValidation(true)
.setDocumentBuilder(db)
.setFile(f)
);
config = builder.getConfiguration();
请注意,验证器必须设置在应用参数的位置。我最初的代码(参见问题)试图以不同的方式覆盖它 - 而且是错误的。