1

javax.xml.parsers.DocumentBuilder可以从单个流(即 XML 文件)构建文档。但是,我找不到任何方法来给它一个模式文件。

有没有办法做到这一点,以便我的 XPath 查询可以执行类型感知查询并返回类型化数据?

4

1 回答 1

1

JAXP API 是为 XPath 1.0 设计的,从未升级为处理 2.0 概念,如模式感知查询。如果您使用的是 Saxon,请使用 s9api 接口而不是 JAXP。

以下是从 s9apiExamples.java 下载的 saxon-resources 中获取模式感知 XPath 的示例:

/**
 * Demonstrate use of a schema-aware XPath expression
 */

private static class XPathC implements S9APIExamples.Test {
    public String name() {
        return "XPathC";
    }
    public boolean needsSaxonEE() {
        return true;
    }
    public void run() throws SaxonApiException {
    Processor proc = new Processor(true);

    SchemaManager sm = proc.getSchemaManager();
    sm.load(new StreamSource(new File("data/books.xsd")));
    SchemaValidator sv = sm.newSchemaValidator();
    sv.setLax(false);

    XPathCompiler xpath = proc.newXPathCompiler();
    xpath.declareNamespace("saxon", "http://saxon.sf.net/"); // not actually used, just for demonstration
    xpath.importSchemaNamespace("");                         // import schema for the non-namespace

    DocumentBuilder builder = proc.newDocumentBuilder();
    builder.setLineNumbering(true);
    builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
    builder.setSchemaValidator(sv);
    XdmNode booksDoc = builder.build(new File("data/books.xml"));

    // find all the ITEM elements, and for each one display the TITLE child

    XPathSelector verify = xpath.compile(". instance of document-node(schema-element(BOOKLIST))").load();
    verify.setContextItem(booksDoc);
    if (((XdmAtomicValue)verify.evaluateSingle()).getBooleanValue()) {
        XPathSelector selector = xpath.compile("//schema-element(ITEM)").load();
        selector.setContextItem(booksDoc);
        QName titleName = new QName("TITLE");
        for (XdmItem item: selector) {
            XdmNode title = getChild((XdmNode)item, titleName);
            System.out.println(title.getNodeName() +
                    "(" + title.getLineNumber() + "): " +
                    title.getStringValue());
        }
    } else {
        System.out.println("Verification failed");
    }
}

// Helper method to get the first child of an element having a given name.
// If there is no child with the given name it returns null

private static XdmNode getChild(XdmNode parent, QName childName) {
    XdmSequenceIterator iter = parent.axisIterator(Axis.CHILD, childName);
    if (iter.hasNext()) {
        return (XdmNode)iter.next();
    } else {
        return null;
    }
}        

}

于 2013-02-05T09:17:45.143 回答