java - 为什么使用 String.intern() 与在 Java 中传递 String 对象会得到不同的结果?

标签 java

我有一个命令行程序来根据 XSD 文件验证 XML。该程序的命令行选项之一是要使用的命名空间,它存储在 String namespace 中。根据我是将已解析的选项作为 namespace 传递还是将调用传递给 namespace.intern(),我会得到不同的验证结果。不同的结果意味着在 XML validator 的某处对命名空间执行的 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);

    }
}

最佳答案

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

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

相关文章:

java - 使用 Perforce 在 Eclipse 中显示行作者

java - 检查是否在 Parse 数据库中找到用户名和电子邮件

java - 使用pdfbox将A4图像定位为PDF文件中的页面

java - 如何引用Java中BeanEditForm(tapestry5)中使用的bean的属性?

java - 如何将base64编码的图像字符串发送到服务器

java - 时差计算错误

java - 第一个 if 语句始终为真,但第二个不是

java - 检查字段是否被覆盖

java - 如何获取包含空格的字符串

java - 执行目标org.codehaus.mojo :findbugs-maven-plugin:3. 0.5的findbugs:findbugs失败:Java返回:1