Saxon:将xdmNode转换为org.w3c.dom.Node

时间:2017-03-14 16:02:02

标签: java dom xpath saxon xpath-2.0

我想将xdmNode转换为dom Node。我找到了以下部分解决方案:

Processor proc = new Processor(false);
XPathCompiler xpath = proc.newXPathCompiler();
Document doc = DocumentUtilities.createEventCountsTestDocument();
XdmNode xdmNode = proc.newDocumentBuilder().wrap(doc);

expression = "/caseFileModel/EventCount/EventCountEvents[EventCmmnId=\"_4cd9cdaabbd244548a32afcd4cf2e1c0\" and EventEventType=\"CREATE\"]/Timestamps/Date[last()]";
value = xpath.evaluate(expression, xdmNode);
XdmNode node = (XdmNode) value;
Node element = ((Node) node.getExternalNode());
System.out.println(element.getTextContent());

createEventCountsTestDocument基于以下XML生成文档:

<caseFileModel>
        </EventCountEvents>
        <EventCountEvents>
            <EventCmmnId>_8dbe1b3fa1a04787b2ef35d153d93ae5</EventCmmnId>
            <EventEventType>CREATE</EventEventType>
            <EventCount>1</EventCount>
            <Timestamps>
                <Date>2017-03-13T16:47:04Z</Date>
            </Timestamps>
        </EventCountEvents>
        <EventCountEvents>
            <EventCmmnId>_4cd9cdaabbd244548a32afcd4cf2e1c0</EventCmmnId>
            <EventEventType>CREATE</EventEventType>
            <EventCount>1</EventCount>
            <Timestamps>
                <Date>2017-03-13T16:47:04Z</Date>
            </Timestamps>
        </EventCountEvents>
    </EventCount>
</caseFileModel>

我得到了正确的输出2017-03-03T12:00:00Z但是elementcom.sun.org.apache.xerces.internal.dom.DeferredElementImpl而不是w3c.dom.Node。这意味着当我致电element.getNodeValue()时,它会返回null。如果我致电element.getFirstChild().getNodeValue(),则会返回正确的值2017-03-03T12:00:00Z。所以似乎有些不对劲但我找不到它。我想找到一种方法将xdmNode转换为w3c.dom.Node而不是转换为DeferredElementImpl

1 个答案:

答案 0 :(得分:1)

这里有几点。我担心这是一个非常复杂的故事。

Saxon有两个用于表示节点的接口:高级接口XdmNode和低级接口NodeInfoXdmNode始终是NodeInfo的包装器。

NodeInfo有很多不同的实现。有两个&#34; native&#34; Saxon中的实现,分别用于TinyTree和LinkedTree模型;还有一些实现可以包装外部节点模型,包括DOM,JDOM,DOM4J,XOM和AXIOM。

如果您开始的XdmNodeNodeInfo的包装器,它本身包装了一个DOM Node,那么您可以使用{{1}到达底层DOM节点}。此方法的签名返回XdmNode.getExternalNode():那是因为包装的节点可能是DOM,或者它可能是JDOM,XOM或其他。

以上段落描述了您目前正在做的事情。您不必担心结果是Object的实例;这只是实现com.sun.org.apache.xerces.internal.dom.DeferredElementImpl接口的众多内部类之一。

如果您开始的org.w3c.dom.Node不是围绕DOM XdmNode的包装器,那么您有两个选择:

  1. 您可以将基础Node包装在NodeInfo类的实例中,该实例提供基础NodeOverNodeInfo节点的DOM视图。但是,这是一个只读视图,因为Saxon节点(通常)是不可变的。

  2. 您可以将Saxon节点复制到DOM节点,最好通过身份转换完成。

  3. 在所有这些中你应该知道Saxon在处理DOM树时,通常比处理自己的内部树模型慢5倍。其中大部分原因是由于在DOM中处理名称和命名空间的效率低下。

    此外,正如您所发现的那样,对于像element.getNodeValue()这样的东西的DOM方法并不总能达到您的预期效果。就个人而言,我像瘟疫一样避免使用DOM。

相关问题