Саксонский XPath API возвращает TinyElementImpl вместо org.w3c.dom. Узел

У меня есть следующий код:

// xpath evaluates to net.sf.saxon.xpath.XPathEvaluator
XPath xpath = XPathFactory.newInstance().newXPath(); 
XPathExpression expression = xpath.compile("/foo/bar");
Object evaluate = expression.evaluate(someXML, XPathConstants.NODE);
Object evaluate2 = expression.evaluate(someXML, XPathConstants.NODESET);

System.out.println(evaluate!=null?evaluate.getClass():"null");
System.out.println(evaluate2!=null?evaluate2.getClass():"null2");

System.out.println(evaluate instanceof Node);
System.out.println(evaluate2 instanceof NodeList);

и это - результат...

class net.sf.saxon.tinytree.TinyElementImpl
class java.util.ArrayList
false
false

Просто для уточнения, если я делаю это:

org.w3c.dom.Node node = (org.w3c.dom.Node)evaluate;

или

org.w3c.dom.NodeList node = (org.w3c.dom.NodeList)evaluate2;

Я получаю a ClassCastException

Как это может быть? согласно узлу Java 1.5 API Солнц и НАБОРУ УЗЛОВ должен отобразиться на org.w3c.dom.Node и org.w3c.dom.NodeList соответственно

Только к clarify2 да я знаю, что Узел является iterface, что getClass () возвращает реальный класс.

7
задан Eran Medan 31 December 2009 в 14:33
поделиться

4 ответа

Хорошо, я понял!

Если метод оценки получает InputSource, то возникает описанная выше ошибка.

например

InputSource someXML = new InputSource(new StringReader("<someXML>...</someXML>)");
Object result = expression.evaluate(someXML, XPathConstants.NODE); 
Node node = (Node) result; // ClassCastException

Тогда результат не реализует org.w3c. dom.Node (TinyElementImpl)

Но если evaluated получает Node (или Document):

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
Document someXML = documentBuilder.parse(new InputSource(new StringReader("<someXML>...</someXML>)"));
Object result = expression.evaluate(someXML, XPathConstants.NODE);
Node node = (Node) result; // works

Это работает, но все же это странно ...

.
6
ответ дан 6 December 2019 в 21:14
поделиться

kdgregory верно подмечено, что Node - это всего лишь интерфейс, и TinyElementImpl реализует этот интерфейс. expression.assess() не может вернуть экземпляр Node, он должен вернуть конкретный класс, который реализует node.

Может быть полезно указать, что вы можете использовать экземпляр TinyElementImpl как в качестве Node, и вы можете легко отбросить экземпляры TinyElementImp в Node.

Например, это должно работать просто отлично:

Node result = (Node) expression.evaluate(someXML, XPathConstants.NODE);

Вы можете использовать result, вызвав любой из методов Node, и передав его любому методу, который принимает Node.

.
-1
ответ дан 6 December 2019 в 21:14
поделиться

Node является интерфейсом. Для реализации необходим конкретный класс. И getClass() возвращает этот конкретный класс.

Правка в ответ на комментарий:

Извините, я не обратил внимания на экземпляр. Глядя на исходный код , кажется, что TinyNodeImpl не реализует org.w3c.dom.Node. И глядя на JDK-документы, кажется, что это не обязательно: документ для javax.xml.XPath ссылается на XPathConstants для типа результата, и он ссылается на "XPath 1. 0 NodeSet data type" (который, если посмотреть на спецификацию XPath 1.0, не определен).

Таким образом, кажется, что возвращаемые из XPath API данные должны быть консистентными только при использовании внутри этого API. Не совсем то, что вы хотели услышать, я уверен. Можете ли вы использовать встроенную реализацию JDK? Я знаю, что она возвращает объекты org.w3c.dom.

.
2
ответ дан 6 December 2019 в 21:14
поделиться

Это немного странно. В Saxon javadoc говорится, что TinyElementImpl не реализует ни один из org.w3c.dom интерфейсов, и все же вы получаете их обратно из оценки XPath.

Думаю, что саксонцы отказываются от стандартной модели DOM в пользу своей. Подозреваю, что XPathConstants.NODE, который вы передаете в evaluation, на самом деле является всего лишь подсказкой. Для XPath выражений разрешено возвращать любые старые вещи (например, Apache JXPath использует XPath выражения для запроса java графиков объектов), поэтому Саксону разрешено возвращать свои собственные типы DOM, а не стандартные org.w3c.

Решение: либо используйте саксонские типы DOM в качестве возвращаемых, либо не используйте Саксону.

.
2
ответ дан 6 December 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: