【发布时间】:2015-03-04 05:18:58
【问题描述】:
我愿意
- 向“子树”添加/删除/更新元素/属性/值
- 能够将更新后的“targetDoc”保存回“target”文件位置。
- 确定最适合此 xpath + 树修改过程的树模型。
我认为我应该能够以某种方式获得一个 MutableNodeInfo 对象,但我不知道该怎么做。我尝试使用 processor.setConfigurationProperty(FeatureKeys.TREE_MODEL, Builder.LINKED_TREE);但这仍然给了我 TinyElementImpl 的底层节点。我需要 xpath 2.0 以避免必须输入默认命名空间,这就是我使用 saxon s9api 而不是 Java 的默认 DOM 模型的原因。如果可能的话,我还想避免使用 xslt/xquery,因为这些树修改是动态完成的,这使得 xslt/xquery 在我的情况下更加复杂。
public static void main(String[] args) {
// XML File namesspace URIs
Hashtable<String, String> namespaceURIs = new Hashtable<>();
namespaceURIs.put("def", "http://www.cdisc.org/ns/def/v2.0");
namespaceURIs.put("xmlns", "http://www.cdisc.org/ns/odm/v1.3");
namespaceURIs.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
namespaceURIs.put("xlink", "http://www.w3.org/1999/xlink");
namespaceURIs.put("", "http://www.cdisc.org/ns/odm/v1.3");
// The source/target xml document
String target = "Path to file.xml";
// An xpath string
String xpath = "/ODM/Study/MetaDataVersion/ItemGroupDef[@OID/string()='IG.TA']";
Processor processor = new Processor(true);
// I thought this tells the processor to use something other than
// TinyTree
processor.setConfigurationProperty(FeatureKeys.TREE_MODEL,
Builder.LINKED_TREE);
DocumentBuilder builder = processor.newDocumentBuilder();
XPathCompiler xpathCompiler = processor.newXPathCompiler();
for (Entry<String, String> entry : namespaceURIs.entrySet()) {
xpathCompiler.declareNamespace(entry.getKey(), entry.getValue());
}
try {
XdmNode targetDoc = builder.build(Paths.get(target).toFile());
XPathSelector selector = xpathCompiler.compile(xpath).load();
selector.setContextItem(targetDoc);
XdmNode subTree = (XdmNode) selector.evaluateSingle();
// The following prints: class
// net.sf.saxon.tree.tiny.TinyElementImpl
System.out.println(subTree.getUnderlyingNode().getClass());
/*
* Here, is where I would like to modify subtree and save modified doc
*/
} catch (SaxonApiException e) {
e.printStackTrace();
}
}
【问题讨论】: