5

我有一个命令行程序来针对 XSD 文件验证 XML。该程序的命令行选项之一是要使用的命名空间,它存储在String namespace. 我得到不同的验证结果,具体取决于我将解析的选项传递为namespace还是传递给namespace.intern(). 不同的结果意味着在 XML 验证器的某处,String对命名空间执行的比较具有不同的结果,即使它们应该具有相同的 ASCII 值集。

这些可能会产生不同的比较结果是否有根本原因?

该类NamespaceFilter(见下文)是使用命名空间值的地方。此类与namespace在内部当前元素上找到的值进行比较startElement,然后分配它。 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);

    }
}
4

1 回答 1

1

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

于 2012-07-03T01:44:57.813 回答