javax.xml.parsers.DocumentBuilder
XML ファイルである単一のストリームからドキュメントを構築できます。ただし、スキーマ ファイルも指定する方法が見つかりません。
XPath クエリが型認識クエリを実行し、型付きデータを返すことができるようにする方法はありますか?
JAXP API は XPath 1.0 用に設計されており、スキーマ認識クエリなどの 2.0 の概念を処理するようにアップグレードされたことはありません。Saxon を使用している場合は、JAXP の代わりに s9api インターフェースを使用してください。
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;
}
}
}