首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Saxon修改XPath 2.0结果树

使用Saxon修改XPath 2.0结果树
EN

Stack Overflow用户
提问于 2015-03-04 05:18:58
回答 2查看 700关注 0票数 1

我想

  1. 向"subTree“添加/删除/更新元素/属性/值
  2. 能够将更新的"targetDoc“保存回”目标“文件位置。
  3. 确定哪个树模型最适合这个xpath +树修改过程。

我想我应该可以得到一个MutableNodeInfo对象,但我不知道如何做到这一点。我尝试使用processor.setConfigurationProperty(FeatureKeys.TREE_MODEL,Builder.LINKED_TREE);但这仍然给我提供了TinyElementImpl的底层节点。我需要XPath2.0来避免输入默认名称空间,这就是为什么我使用saxon而不是s9api的默认DOM模型。如果可能的话,我还想避免使用xslt/xquery,因为这些树修改是动态的,使xslt/xquery在我的情况下更加复杂。

代码语言:javascript
运行
复制
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();
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-05 10:59:09

我认为您可以向Saxon提供一个DOM节点并针对它运行XPath,但是如果您不为Saxon的原生树使用文档构建器,则使用javax.xml.parsers.DocumentBuilder构建DOM,一旦您有了W3C DOM节点,就可以使用Saxon DocumentBuilderwrap方法将其提供给Saxon。下面是从S9APIExamples.java文件Saxon 9.6资源文件中获取的示例代码

代码语言:javascript
运行
复制
        // Build the DOM document
        File file = new File("data/books.xml");
        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
        dfactory.setNamespaceAware(true);
        javax.xml.parsers.DocumentBuilder docBuilder;
        try {
            docBuilder = dfactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new SaxonApiException(e);
        }
        Document doc;
        try {
            doc = docBuilder.parse(new InputSource(file.toURI().toString()));
        } catch (SAXException e) {
            throw new SaxonApiException(e);
        } catch (IOException e) {
            throw new SaxonApiException(e);
        }
        // Compile the XPath Expression
        Processor proc = new Processor(false);
        DocumentBuilder db = proc.newDocumentBuilder();
        XdmNode xdmDoc = db.wrap(doc);
        XPathCompiler xpath = proc.newXPathCompiler();
        XPathExecutable xx = xpath.compile("//ITEM/TITLE");
        // Run the XPath Expression
        XPathSelector selector = xx.load();
        selector.setContextItem(xdmDoc);
        for (XdmItem item : selector) {
            XdmNode node = (XdmNode) item;
            org.w3c.dom.Node element = (org.w3c.dom.Node) node.getExternalNode();
            System.out.println(element.getTextContent());
        }

还有一些示例展示了如何在JDOM和其他可变树实现中使用Saxon,但我认为您需要使用Saxon或EE来直接支持这些实现。

票数 1
EN

Stack Overflow用户

发布于 2015-03-05 11:42:37

Saxon中的MutableNodeInfo接口是专为满足XQuery更新的需要而设计的,我建议不要尝试直接从XQuery使用它;在处理方法调用时,除了XQuery更新的调用之外,实现不太可能是健壮的。

事实上,Saxon NodeInfo接口通常是作为XPath的目标而不是为用户编写的Java代码而设计的。因此,我建议使用第三方树模型;我最喜欢的是JDOM2和XOM。这两种方法都允许您将直接Java导航和更新与使用Saxon的XPath 2.0导航相结合。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28847146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档