我有一个命令行程序来针对XSD文件验证XML。该程序的命令行选项之一是要使用的 namespace ,该 namespace 存储在String namespace中。根据将解析的选项作为namespace传递还是将调用传递给namespace.intern(),我将得到不同的验证结果。不同的结果意味着在XML validator 中的某个地方,对命名空间执行的String比较具有不同的结果,即使它们应具有相同的ASCII值集也是如此。
这些可能会产生不同的比较结果,这是否有根本原因?NamespaceFilter类(请参阅下文)是使用 namespace 值的位置。此类将namespacestartElement中当前元素上找到的值进行比较,然后进行分配。 startElement由XML阅读器调用。
这些是validateAgainstXSD内部的行变体:String.intern()NamespaceFilter nsf = new NamespaceFilter(XMLReaderFactory.createXMLReader(), namespace.intern());结果:
验证uart.xml。
字符串对象原样NamespaceFilter nsf = new NamespaceFilter(XMLReaderFactory.createXMLReader(), namespace);结果:
错误发生在4:cvc-complex-type.2.4.a:发现从元素'fileVersion'开始的无效内容。预期为“{{myNamespace”:fileVersion}”之一。
上下文中的来源

public static void validateAgainstXSD(File file, File schemaFile, String namespace) {

    try {
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

        Schema xsdScheme = factory.newSchema(schemaFile);

        Validator validator = xsdScheme.newValidator();
        ErrorHandler eh = new DefaultErrorHandler();

        validator.setErrorHandler(eh);

        // Create namespace replacement filter
        NamespaceFilter nsf = new NamespaceFilter(XMLReaderFactory.createXMLReader(), namespace.intern());

        // Load the XML source
        SAXSource source = new SAXSource(nsf, new InputSource(new FileInputStream(file)));

        validator.validate(source, null);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

private static class NamespaceFilter extends XMLFilterImpl {

    private String requiredNamespace;

    public NamespaceFilter(XMLReader parent) {
        super(parent);
    }

    public NamespaceFilter(XMLReader parent, String namespace) {
        this(parent);

        requiredNamespace = namespace;
    }

    @Override
    public void startElement(String uri,
            String localName,
            String qName,
            Attributes atts)
            throws SAXException {

        if (!uri.equals(requiredNamespace)) {
            uri = requiredNamespace;
        }
        super.startElement(uri, localName, qName, atts);

    }
}

最佳答案

您还需要使用类似的逻辑来覆盖endElement()。否则,开始和结束元素URI可能不匹配。 XMLFilterImpl可能在==而不是.equals()上匹配它们。

关于java - 为什么在Java中通过String.intern()与传递String对象得到不同的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11300300/

10-16 00:01