 | Обработка данных сервиса
Теперь, когда у нас есть параметры, выбранные пользователем, настало время пустить их в работу при обработке данных. Все, что вам нужно сделать - это заменить текущую операцию, построенную на XPath, операцией из онтологии.
Передача онтологии
Сначала нужно убедиться, что онтология доступна там, где она нужна. В данном случае это означает, что она должна быть доступна методу renderService() сервлета (см. листинг 26).
Листинг 26. Передача онтологии
...
public static Node renderService(String query, Service svc,
Document hostDoc, MashupOntologyReader ont ) {
Document document = getData(query, svc);
...
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
...
for (int k=0; k < svcs.length; k++){
Service svc = svcs[k];
Node renderedService = renderService(
svc.getRESTRequest(ont)+query, svc, hostDoc, ont);
if (renderedService != null){
...
|
После того как мы включили онтологию в подпись для метода renderService(), все, что нам остается сделать - добавить ее к вызову этого метода.
Загрузка новых данных
Когда мы передаем онтологию методу renderService(), она содержит все определения, но не содержит данных. К счастью, добавить данные очень просто (см. листинг 27).
Листинг 27. Загрузка новых данных
...
Document document = getData(query, svc);
String source = "http://example.com/store#";
Model model = ont.getOnt().getDocumentManager()
.getModel("http://example.com/store");
DOM2Model.createD2M(source, model).load(document);
OntModel ontModel = (OntModel)model;
Node serviceElement = hostDoc.createElement("span");
DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
...
|
В классе DOM2Model реализован статический метод createD2M(), который позволяет ссылаться на модель из обсуждаемого пространства имен. Теперь мы можем с легкостью загрузить документ DOM, который представляет данные, возвращенные сервисом и преобразованные в общую онтологическую форму.
Разницу в модели до и после этой операции можно увидеть с помощью метода model.write(), но для того, чтобы сэкономить место, я оставлю это упражнение вам для самостоятельного изучения.
Извлечение индивидных концептов на основе output type
Следующим шагом мы должны извлечь отдельные результаты. Изначально мы делали это с помощью значения атрибута recordExp выражения XPath; теперь это нужно делать с помощью outputType (см. листинг 28).
Листинг 28. Извлечение индивидных концептов на основе outputType
...
DOM2Model.createD2M(source, model).load(document);
OntModel ontModel = (OntModel)model;
Node serviceElement = hostDoc.createElement("span");
DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
Node toImport = null;
// Get individuals based on output type
ExtendedIterator recordNodes = ontModel.listIndividuals(
ontModel.getOntClass(svc.recordExp));
for (ExtendedIterator i = recordNodes; i.hasNext(); ) {
Individual thisRecord = (Individual)i.next();
Document templateDoc = builder.parse(new InputSource(
new StringReader(svc.template)));
String expression = "//value";
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList templateNodes = (NodeList) xpath.evaluate(
expression, templateDoc, XPathConstants.NODESET);
for (int j=0; j < templateNodes.getLength(); j++){
Node thisNode = templateNodes.item(j);
Node parentNode = thisNode.getParentNode();
// Get the appropriate property value and replace
//it in the template
if ( (Boolean)xpath.evaluate(
svc.elementValues.elementAt(j).toString(),
thisRecord, XPathConstants.BOOLEAN)) {
Node valueNode = (Node)xpath.evaluate(
svc.elementValues.elementAt(j).toString(),
thisRecord, XPathConstants.NODE);
String valueText = valueNode.getTextContent();
Node replacementNode =
templateDoc.createTextNode(valueText);
parentNode.replaceChild(replacementNode,
thisNode);
}
}
expression = "//@value";
templateNodes = (NodeList) xpath.evaluate(expression,
templateDoc, XPathConstants.NODESET);
for (int j=0; j < templateNodes.getLength(); j++){
Attr thisNode = (Attr) templateNodes.item(j);
Element parentElement =
(Element)thisNode.getOwnerElement();
parentElement.removeAttribute("value");
if ( (Boolean)xpath.evaluate(
svc.attributeValues.elementAt(j).toString(),
thisRecord, XPathConstants.BOOLEAN)) {
Node valueNode = (Node)xpath.evaluate(
svc.attributeValues.elementAt(j).toString(),
thisRecord, XPathConstants.NODE);
parentElement.setAttribute(
thisNode.getNodeValue(),
valueNode.getTextContent());
}
}
...
|
Сначала мы получаем итератор индивидных концептов класса, представленного outputType для сервиса, хранящегося в атрибуте recordExp. После этого мы можем организовать цикл по каждому из этих индивидных концептов так же, как мы делали это раньше, но на этот раз мы используем индивидный концепт thisRecord, а не запись в NodeList.
Это все изменения к этому моменту. Все прочие операции XPath остаются на своих местах, но мы заменили ссылки на recordNode объектом thisRecord, поэтому компиляция сервлета пройдет успешно. Однако пока он не выдаст нам никаких результатов, поскольку он выполняет поиск выражений XPath для данных, которых не существует.
Извлечение свойства элемента
Теперь, когда мы прошли по всем записям, нам нужно заменить подстановочные символы шаблона необходимыми данными. Шаблон создавался пользователем, но поскольку мы рассматриваем метод renderService(), ничего не изменилось; он все так же хранится в атрибуте template класса Service. Изменилось то, как мы будем работать с записями в elementValues и attributeValues Vectors. Раньше они представляли собой выражения XPath, которые мы использовали для извлечения определенных данных из XML, возвращаемого сервисом, а теперь они являются URI Property, которые мы будем использовать для запроса данных с помощью блока рассуждений онтологии.
Начнем с получения отдельных свойств (см. листинг 29).
Листинг 29. Извлечение свойства элемента
...
String expression = "//value";
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList templateNodes = (NodeList) xpath.evaluate(
expression, templateDoc, XPathConstants.NODESET);
for (int j=0; j < templateNodes.getLength(); j++){
Node thisNode = templateNodes.item(j);
Node parentNode = thisNode.getParentNode();
// Get the appropriate property value and replace
//it in the template
Property prop2 = ont.getOnt().getProperty(
svc.elementValues.elementAt(j).toString());
...
}
}
...
|
Этот процесс очень прост, поскольку информация хранится в elementValues Vector в виде строки, представляющей URI свойства.
Получение соответствующего значения
Как только у нас появилось Property, мы можем использовать его для извлечения значения из данных в онтологии. (Надо помнить, что теперь в онтологии содержатся данные, возвращенные сервисом.) (См. листинг 30).
Листинг 30. Получение значения
...
for (int j=0; j < templateNodes.getLength(); j++){
Node thisNode = templateNodes.item(j);
Node parentNode = thisNode.getParentNode();
// Get the appropriate property value and replace
//it in the template
Property prop2 = ont.getOnt().getProperty(
svc.elementValues.elementAt(j).toString());
RDFNode propVal2 =
thisRecord.getPropertyValue(prop2);
if ( propVal2 != null ) {
String valueText;
if (propVal2.isLiteral()){
valueText = ((Literal)propVal2).getString();
} else {
valueText = propVal2.toString();
}
Node replacementNode =
templateDoc.createTextNode(valueText);
parentNode.replaceChild(replacementNode,
thisNode);
} else {
System.out.println("propval2 is null");
}
}
...
|
Как только мы получили значение путем применения метода getPropertyValue() к объекту thisRecord, нужно убедиться, что оно содержит данные. Если это не так, нам нужно извлечь литеральное значение, если оно является таковым, или String-версию значения свойства.
Так или иначе, теперь в valueText содержатся соответствующие данные, возвращаемые сервисом, и мы можем дать сервлету возможность обработать их так же, как и раньше, используя их для замещения соответствующего подстановочного элемента value в шаблоне.
Извлечение свойств атрибута
Процесс практически идентичен для элементов вектора attributeValues (см. листинг 31).
Листинг 31. Извлечение свойств атрибута
...
expression = "//@value";
templateNodes = (NodeList) xpath.evaluate(expression,
templateDoc, XPathConstants.NODESET);
for (int j=0; j < templateNodes.getLength(); j++){
Attr thisNode = (Attr) templateNodes.item(j);
Element parentElement =
(Element)thisNode.getOwnerElement();
// Get the appropriate property value and replace
//it in the template
parentElement.removeAttribute("value");
Property prop3 = ont.getOnt().getProperty(
svc.attributeValues.elementAt(j).toString());
RDFNode propVal3 =
thisRecord.getPropertyValue(prop3);
if ( propVal3 != null ) {
String valueText;
if (propVal3.isLiteral()){
valueText = ((Literal)propVal3).getString();
} else {
valueText = propVal3.toString();
}
parentElement.setAttribute(
thisNode.getNodeValue(), valueText);
} else {
System.out.print("prop3 is null");
}
}
...
|
И опять единственным, что мы изменяем, остается способ наполнения переменной valueText; существующий код, который замещает подстановочные атрибуты шаблона, остается неизменным.
Конечный результат
Наконец, мы готовы посмотреть на результат. Используя шаблон, введенный в разделе Вывод свойств, мы должны получить результат, похожий на приведенный на рисунке 7.
Рисунок 7. Конечный результат
Конечно же, если вы введете другой шаблон, вы получите совершенно другой результат, но в этом и состоит весь смысл. Теперь пользователи могут получать ту информацию, которую хотят, и выбирать, как она будет выглядеть на странице.
|  |