#java #xml #validation #xpath #jaxp
#java #xml #проверка #xpath #jaxp
Вопрос:
Я полагаюсь на реализацию JAXP по умолчанию и использую Oracle JRE. При вычислении XPath, который содержит неизвестный префикс пространства имен, он не выдает (ожидаемое) исключение.
Когда я запускаю то же приложение на IBM JRE, все в порядке, и оно выдает ожидаемое исключение javax.xml.xpath.XPathExpressionException: org.apache.xpath.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace
Я использую следующий код, который пытается получить доступ к недопустимому неизвестному пространству имен
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(true);
documentBuilderFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
Document doc = builder.parse(xmlFile_);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xpath.evaluate("path/to/node/unknowns:@bla", doc,
XPathConstants.NODESET);
Вопрос:
Как я могу принудительно выполнить эту проверку независимо от реализации JAXP?
Комментарии:
1. Можете ли вы опубликовать код, отвечающий за инициализацию и настройку экземпляра DocumentBuilderFactory, а также экземпляров XPathFactory и XPath?
2. Какой класс объекта возвращает XPathFactory.newInstance()?
Ответ №1:
Попробуйте установить a NamespaceContext
на вашем XPath
экземпляре:
public final class NSValidator {
private NSValidator() {
}
private static final NamespaceContext INSTANCE = new NamespaceContext() {
@Override public String getNamespaceURI(String prefix) {
return null;
}
@Override public String getPrefix(String namespaceURI) {
return null;
}
@Override public Iterator<?> getPrefixes(String namespaceURI) {
return Collections.emptyList()
.iterator();
}
};
public static NamespaceContext noNamespaces() {
return INSTANCE;
}
}
Комментарии:
1. Спасибо, что сработало. Похоже, что IBM JRE имеет NamespaceContext по умолчанию, в то время как Oracle JRE этого не имеет. Последнее приводит к тому, что ошибки, связанные с контекстами, не будут сообщаться по умолчанию.