Saxon distinct-values抛出异常



我正在尝试使用Saxon运行"不同值"XPath。下面是我的代码:

 @Test
public void testAttributeSelect() throws XPathFactoryConfigurationException {
     System.setProperty("javax.xml.xpath.XPathFactory:"
     + NamespaceConstant.OBJECT_MODEL_SAXON,
     "net.sf.saxon.xpath.XPathFactoryImpl");
      System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
    "net.sf.saxon.dom.DocumentBuilderFactoryImpl");
      String xpathString = "distinct-values(//id)";
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true);
    try {
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        System.out.println(builder.getClass());
        Document doc =
       builder.parse(this.getClass().getResourceAsStream("parametrizedId_feed.xml"));
        System.out.println(doc.getClass());
        XPath xpath =
      XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON).newXPath();
        NodeList s1 = (NodeList) 
        xpath.evaluate("/matches", doc, XPathConstants.NODESET);
       NodeList s = (NodeList) 
       xpath.evaluate(xpathString, s1 , XPathConstants.NODESET);

我得到了这个异常:

javax.xml.xpath。无法为类net.sf.saxon.dom.DOMNodeList的节点定位对象模型实现net.sf.saxon.xpath.XPathExpressionImpl.evaluate (XPathExpressionImpl.java: 300)net.sf.saxon.xpath.XPathEvaluator.evaluate (XPathEvaluator.java: 434)ca.cbc.panacea.playground.TestXpath.testAttributeSelect (TestXpath.java: 43)在sun.reflect.NativeMethodAccessorImpl。invoke0(本地方法)sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java: 39)

Saxon-dom jar文件在类路径中。另外,如果我试图直接在doc对象上调用'distinct-values',我会得到一个:

net.sf.saxon.trans。xpatheexception:扩展函数需要类。无法转换net.sf.saxon.value.UntypedAtomicValue类提供的值net.sf.saxon.dom.DOMObjectModel.convertXPathValueToObject (DOMObjectModel.java: 395)net.sf.saxon.dom.DOMObjectModel.access 000美元(DOMObjectModel.java: 42)net.sf.saxon.dom.DOMObjectModel 5.美元转换(DOMObjectModel.java: 166)net.sf.saxon.xpath.XPathExpressionImpl.evaluate (XPathExpressionImpl.java: 352)net.sf.saxon.xpath.XPathEvaluator.evaluate (XPathEvaluator.java: 434)

我不知道这里发生了什么事。谷歌也不会!

首先要说明的是DOM和Saxon不能很好地结合在一起。如果你是为了在树上使用Saxon而构建树,使用Saxon的原生树模型而不是DOM——它要快十倍。

您提到Saxon -dom.jar这一事实意味着您一定是在使用一个相当旧的Saxon版本,可能是一个不再支持的版本。所以我的下一个建议是使用最新的版本。

我注意到的另一件事是,您要求使用XPath处理器来处理Saxon对象模型,然后使用它来处理DOM对象模型。我不知道这是否可行。(如果您想确保加载Saxon而不是其他XPath引擎,例如,因为您想要XPath 2.0,那么最好完全跳过JAXP工厂机制,直接实例化Saxon实现。)

我找到了一个从Saxon中检索NodeList的解决方案。在执行语句"List s = (List) xpath"之后。您可以使用下面的代码从List中读取节点和节点值:

getagvalue("商品名",NodeOverNodeInfo.wrap((NodeInfo) .get(i)))"COMMODITYNAME"是你想要读取值的XML中的节点,NodeOverNodeInfo.wrap((NodeInfo) .get(i))是当前从"s"列表中指向的节点。

私有字符串getTagValue(字符串字符串,NodeOverNodeInfo nodeInfo){

    NodeList nodeList = nodeInfo.getChildNodes(); //list of  XML node
    Node nodeValue = null;
    String strReturn = null;
    for (int iItem=0;iItem<nodeList.getLength();iItem++)
    {
        nodeValue = nodeList.item(iItem).getFirstChild();   
        if (nodeValue != null && strag.equalsIgnoreCase(nodeValue.getParentNode().getNodeName()))
        {
            strReturn = nodeValue.getNodeValue();
            //punta la tag index
            //System.out.println(nodeValue.getParentNode().getNodeName()); //this is the node name
            //System.out.println(nodeValue.getNodeValue()); // this is the node value
        }
    }
return strReturn;
}

再见,Valerio

这不是一个答案,我只是想评论一下Michael的回答,但是评论是非常有限的。谢谢你的回复,迈克尔。我的依赖项如下:

<dependency>
        <groupId>net.sourceforge.saxon</groupId>
        <artifactId>saxon</artifactId>
        <version>9.1.0.8</version>
    </dependency>
    <dependency>
        <groupId>net.sourceforge.saxon</groupId>
        <artifactId>saxon</artifactId>
        <version>9.1.0.8</version>
        <classifier>xpath</classifier>
    </dependency>
    <dependency>
    <groupId>net.sourceforge.saxon</groupId>
        <artifactId>saxon</artifactId>
        <version>9.1.0.8</version>
        <classifier>dom</classifier>
    </dependency>

我猜这是maven仓库中最新的。如果我遗漏了什么,请告诉我。您对情况的解释非常好,只是我需要一个示例代码来弄清楚如何做到这一切。我做了以下更改,它工作了!

InputSource is = new InputSource(this.getClass().getResourceAsStream("parametrizedId_feed.xml"));
         SAXSource ss = new SAXSource(is);
        XPath xpath =  XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON).newXPath();
        NodeInfo doc1 = ((XPathEvaluator)xpath).setSource(ss);
        System.out.println("Loaded XPath Provider " + xpath.getClass().getName());
       List s = (List) xpath.evaluate(xpathString, doc1 , XPathConstants.NODESET);
        for(int i = 0 ; i<s.size(); i++){
            String n = (String) s.get(i);
            System.out.println(n);
        }

这就是你所说的撒克逊树模型吗?唯一的问题是evaluate方法返回List而不是NodeList。我想提一下,我们之所以使用Saxon,是因为它具有极好的速度和更好的功能,因此代码库对JAXP API有许多依赖关系,这是一个难以克服的问题。

最新更新