我试图忽略XML文件的根元素中提供的命名空间,以便针对外部模式进行验证。不幸的是,我无法改变一些项目,因为这是一个交织在一起的遗留系统。
我已经读过(这里是SO)我应该能够在输入XML周围使用过滤器,但它似乎不起作用,感觉我错过了一些东西。当我运行验证时,我收到以下错误消息:
org.xml.sax.SAXParseException:cvc-elt.1:找不到元素'MY_ROOT_ELEMENT'的声明。
这是带有命名空间信息的XML文件的开头:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MY_ROOT_ELEMENT xmlns="http://www.mycompany.net/somename"
schemaVersion="2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mycompany.net/somename
myschema.xsd">
...
</MY_ROOT_ELEMENT>
以下是模式的伴随开头,其中定义了MY_ROOT_ELEMENT:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="MY_ROOT_ELEMENT" type="MY_ROOT_ELEMENT"/>
StreamReaderDelegate,用于忽略命名空间:
private static final class NoNamespaceStreamReaderDelegate extends StreamReaderDelegate {
NoNamespaceStreamReaderDelegate(XMLStreamReader reader) {
super(reader);
}
@Override
public NamespaceContext getNamespaceContext() {
return super.getNamespaceContext();
}
@Override
public int getNamespaceCount() {
return 1;
}
@Override
public String getNamespacePrefix(int index) {
if (index == 0) {
return "xsi";
}
throw new NullPointerException();
}
@Override
public String getNamespaceURI() {
return null;
}
@Override
public String getNamespaceURI(String prefix) {
if ("xsi".equals(prefix)) {
return XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
}
return null;
}
@Override
public String getNamespaceURI(int index) {
if (index == 0) {
return XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
}
return null;
}
}
最后,如何调用验证:
// reads from the classpath
XMLStreamReader reader = createReaderFromSource();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(inputSource.getSchema());
Source readerSource = new StAXSource(new NoNamespaceStreamReaderDelegate(reader));
Validator validator = schema.newValidator();
validator.validate(readerSource);
答案 0 :(得分:0)
为后人发布此信息。
似乎答案是设置&#34; IS_NAMESPACE_AWARE&#34; XMLInputFactory上的属性为false,然后使用StreamReaderDelegate确保忽略xsi:schemaLocation。许多包装器库都是这个API的一部分,但对于the default StAX implementation,您需要设置属性。
一旦我宣布了以下内容并实施了代表,一切都像魅力一样。
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);