有没有办法为Java文档提供XPath查询的XML模式

时间:2013-02-04 22:32:34

标签: java xpath xsd

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

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

1 个答案:

答案 0 :(得分:1)

JAXP API是为XPath 1.0设计的,从未升级为处理类似于架构的查询等2.0概念。如果您使用的是Saxon,请使用s9api接口而不是JAXP。

以下是在saxon-resources下载中从s9apiExamples.java中获取的模式感知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;
    }
}        

}

相关问题