简体   繁体   English

在使用流分析器(SJSXP)进行验证之前,尝试从XML中剥离名称空间

[英]Trying to strip namespace from XML before validating using Streaming parser (SJSXP)

I'm trying to ignore the namespaces provided in the root element of an XML file, in order to validate against an external schema. 我试图忽略XML文件根元素中提供的命名空间,以便针对外部架构进行验证。 Unfortunately, I cannot change some of the items, as this is a heavily intertwined legacy system. 不幸的是,我无法更改某些项目,因为这是一个相互交织的遗留系统。

I've read (here on SO) that I should be able to use filters around the input XML, but it doesn't seem to work and feel like I'm missing something. 我已经阅读(在SO上),我应该能够在输入XML周围使用过滤器,但是它似乎不起作用,感觉好像我缺少了一些东西。 When I run the validation, I get the following error message: 运行验证时,出现以下错误消息:

org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'MY_ROOT_ELEMENT'. org.xml.sax.SAXParseException:cvc-elt.1:找不到元素'MY_ROOT_ELEMENT'的声明。

Here's the beginning of the XML file with the namespace info: 这是带有名称空间信息的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>

Here's the accompanying beginning of the schema where MY_ROOT_ELEMENT is defined: 这是定义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"/>

The StreamReaderDelegate which is used to ignore the namespace: 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;
    }
}

And lastly, how the validation is called: 最后,验证的调用方式:

// 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);

Posting this for posterity's sake. 为了后代的缘故发布此消息。

Seems like the answer is to set the "IS_NAMESPACE_AWARE" property on the XMLInputFactory to false, and then use the StreamReaderDelegate to make sure the xsi:schemaLocation is ignored. 似乎答案是将XMLInputFactory的“ IS_NAMESPACE_AWARE”属性设置为false,然后使用StreamReaderDelegate来确保忽略xsi:schemaLocation。 Many wrapper libraries make this part of their API, but for the default StAX implementation , you need to set the property. 许多包装器库都将此部分作为其API的一部分,但是对于默认的StAX实现 ,您需要设置属性。

Once I declared the following, and implemented the Delegate, everything worked like a charm. 一旦我声明以下内容并实现了委托,一切就如魅力一般。

XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM