XSLT Saxon

  • Автор темы Автор темы oshmianski
  • Дата начала Дата начала
XPath бывает двух версий: 1.0 и 2.0. Вы наверняка заюзали что-то из  xpath 2.0 ( интересно кстати что именно ). А лотус как обычно слегка не успевает за ходом технического прогресса и штатный парсер вторую версию не поддерживает.
нет, не 2.0, потому что парсер, в котором все работало, был SAXON 6.5.5, а он поддерживает только 1.0. Отлаживала я в классной штуке Oxygen XML editor, там есть реально XSL-дебагер, оч удобно))

А само Xpath-выражение в селекте:

<xsl:value-of select="normalize-space($dxl/document/item[@name=$dxlName]//.)"/>

В переменную $dxl загружен преобразуемый документ, выгруженный из Лотуса NotesDXLexporter, $dxlName - переменная, содержащая имя поля в лотусе (для замены по справочнику для передачи по определенному формату). Если интересно, могу всю трансформацию выложить.

и вперед, согласно документации saxon и примерам из гугла
над этим и бьюсь, помощи попросила...
 
oshmianski2,
Можно нубовский вопрос:

как я поняла, второе - это функция LS, допустим, где-нибудь в скриптовой библиотеке, которую мы потом вызовем. Это мне ясно.

А первое? Еще одна джавовская библиотека, как интерфейс к саксону? Куда этот код положить?..
 
нет, не 2.0, потому что парсер, в котором все работало, был SAXON 6.5.5, а он поддерживает только 1.0. Отлаживала я в классной штуке Oxygen XML editor, там есть реально XSL-дебагер, оч удобно))

А само Xpath-выражение в селекте:

<xsl:value-of select="normalize-space($dxl/document/item[@name=$dxlName]//.)"/>

В переменную $dxl загружен преобразуемый документ, выгруженный из Лотуса NotesDXLexporter, $dxlName - переменная, содержащая имя поля в лотусе (для замены по справочнику для передачи по определенному формату). Если интересно, могу всю трансформацию выложить.
На первый взягляд выглядит нормально. Должно работать. Вот бы действительно посмотреть на весь шаблон целиком...
над этим и бьюсь, помощи попросила...
а что конкретно не получается? Подцепить jar к агенту? Написать код, осуществляющий преобразование?
 
Вся трансформация:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"xslt"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='xml'><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<ApplicationFile>
<xsl:variable name="dxl" select="/"/>
<xsl:for-each select="document('dictionary.xml')/root/item">
<xsl:variable name="equiName">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:variable name="dxlName">
<xsl:value-of select="./@dxlName"/>
</xsl:variable>
<xsl:element name="{$equiName}">
<xsl:value-of select="normalize-space($dxl/document/item[@name=$dxlName]//.)"/>
</xsl:element>
</xsl:for-each>
</ApplicationFile>
</xsl:template>
</xsl:stylesheet>[/CODE]
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"Исходный документ (который грузится в $dxl) - не весь, конечно, из-за большого объема"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='xml'><?xml version="1.0" encoding="UTF-8"?>
<document form="CreditClaim" version="8.5" replicaid="44257ABB0031C58A" maintenanceversion="2.0">
<noteinfo unid="60EFAF5992C1C54B44257AA10044B9C1" noteid="922" sequence="44">
<created>
<datetime>20121024T163040,01+04</datetime>
</created>
<modified>
<datetime>20121223T163416,73+04</datetime>
</modified>
<revised>
<datetime>20121223T163416,72+04</datetime>
</revised>
<lastaccessed>
<datetime>20121223T163416,72+04</datetime>
</lastaccessed>
<addedtofile>
<datetime>20121210T104500,15+04</datetime>
</addedtofile>
</noteinfo>
<item name="PlaceFact">
<textlist>
<text/>
</textlist>
</item>
<item name="BackTo">
<textlist>
<text>Новая</text>
</textlist>
</item>
<item name="$WebFlags">
<textlist>
<text>V</text>
</textlist>
</item>
<item name="$ConflictAction">
<textlist>
<text>2</text>
</textlist>
</item>
<item name="Status">
<textlist>
<text>Проверка СБ</text>
</textlist>
</item>
<item name="DOcode">
<textlist>
<text/>
</textlist>
</item>
<item name="IsArchive">
<textlist>
<text/>
</textlist>
</item>
<item name="ArchiveDate">
<datetimelist>
<datetime>20121126</datetime>
</datetimelist>
</item>
<item name="PreviousStatus">
<textlist>
<text>Подготовка документов</text>
</textlist>
</item>
<item name="VisaDecision">
<textlist>
<text>Возврат на этап Заведения заявки</text>
</textlist>
</item>
<item name="ClaimNo">
<numberlist>
<number>226</number>
</numberlist>
</item>
<item name="EmployeeYN">
<textlist>
<text/>
</textlist>
</item>
<item name="ClaimID">
<textlist>
<text>60EFAF5992C1C54B44257AA10044B9C1</text>
</textlist>
</item>
<item name="FormName">
<textlist>
<text>Заемщик</text>
</textlist>
</item>
<item name="CreationDate">
<textlist>
<text>24.10.2012 16:30:40</text>
</textlist>
</item>
<item name="VisitDate">
<textlist>
<text/>
</textlist>
</item>
<item name="F">
<textlist>
<text>ЧЕРКУНОВА</text>
</textlist>
</item>
<item name="I">
<textlist>
<text>ОЛЬГА</text>
</textlist>
</item>
<item name="O">
<textlist>
<text>МИРОСЛАВОВНА</text>
</textlist>
</item>
<item name="S">
<textlist>
<text>Жен</text>
</textlist>
</item>
<item name="BirthDate">
<datetimelist>
<datetime>19761020</datetime>
</datetimelist>
</item>
<item name="BirthPlace">
<textlist>
<text>Г. МОСКВА</text>
</textlist>
</item>
<item name="Citizenship">
<textlist>
<text>Российская Федерация</text>
</textlist>
</item>
<item name="NativeCountry">
<textlist>
<text/>
</textlist>
</item>
<item name="ChangeFIO">
<textlist>
<text>да</text>
</textlist>
</item>
<item name="PreviousFIO">
<textlist>
<text>ДМИТРИЕВА</text>
</textlist>
</item>
</document>[/CODE]

Атрибут xmlns удаляется первой трансформацией (с ним вообще ничего не работает), она запускается и на родном лотусовом парсере. Т.е. после первой трансформации у меня в нотесстриме все то же, но без xmlns. Нужно применить вторую трансформацию, которая из выгрузки сформирует xml-запрос по нужному формату. XSL-трансформация приведена выше, в oxygen приводит к нужному результату, все отлично работает. Далее я создала java-библиотеку, куда импортировала SAXON. Как я понимаю, нужно вызвать ее функцию или метод, которая реализует трансформацию. Как именно это сделать? Хелпа по саксону 6.5.5 адекватного нету.
ЗЫ:для больших кусков - ставьте спойлер
 
"обычная практика", при последовательных трансформациях, задавать промежуточный нэймспэйс
др. вопрос - почему низя обойтись одной трансформацией?
 
а ваще нэйм спэсы м.б. такие xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ldn="http://www.lotus.com/dxl"
и к нотусёвым сучностям применять ихний спэйс как-то типа:
match="ldn:document/*[name()!='item']"
select="ldn:object/ldn:file/ldn:filedata/text()"

Добавлено: ежели нужно получать дополнительны префик - его надо определить и исключить из обработки
для ФОП, например, так: xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo"
 
oshmianski2,
Можно нубовский вопрос:

как я поняла, второе - это функция LS, допустим, где-нибудь в скриптовой библиотеке, которую мы потом вызовем. Это мне ясно.

А первое? Еще одна джавовская библиотека, как интерфейс к саксону? Куда этот код положить?..

Да, это java библиотека с единственным классом и функцией TrasformFFF, куда передаются пути к соответствующим файлам.
Интерфейсом это вряд ли можно назвать. Просто подменяется системный TransformerFactory на saxon и выполяется транформация.
Результат ложиться в файл resultXML.

Как это у меня:
1) Создается исходный xml и выкладывается на диск = файл sourceXML.
2) Подготавливается и выкладывается на диск XSL = файл sourceXSL.
3) Выполняется saxon трансформация = файл resultXML.
4) Делаем с файлом resultXML что захотим (у меня сразу открывался в MS Excel, т.е. XSL был соответствующий)
 
Да, это java библиотека с единственным классом и функцией TrasformFFF, куда передаются пути к соответствующим файлам.
Интерфейсом это вряд ли можно назвать. Просто подменяется системный TransformerFactory на saxon и выполяется транформация.
Результат ложиться в файл resultXML.

Как это у меня:
1) Создается исходный xml и выкладывается на диск = файл sourceXML.
2) Подготавливается и выкладывается на диск XSL = файл sourceXSL.
3) Выполняется saxon трансформация = файл resultXML.
4) Делаем с файлом resultXML что захотим (у меня сразу открывался в MS Excel, т.е. XSL был соответствующий)
Сделала следующее:
1) создала java-либу с единственным классом SaxonXML2transformer. В нем тот код, который вы давали, включая импорт.
2) создала LS-либу, в ней класс transformer, у него функция E2E_TransformSaxon.
3) ну и наконец агент, который вызывает эту функцию класса и передает ей три пути к файлам, как вы писали.

Все валится на строчке Call saxonObj.TrasformFFF (sXML, sXSL, sTargetXML) - после нее идет на обработчик ошибок.

Что не так?
 
а jar положили в %notes%\jvm\lib\ext\?
 
Сначала не положила, конечно... Я ранее jar импортировала в отдельную либу)) потом положила, но все равно не работает, плюс еще при запуске клиента теперь выдается ошибка, что:

An internal error occurred during: "Getting Current Location".
java.lang.NullPointerException

А положить надо было на клиенте или на сервере? Я на своей машине положила, потому что агент на ней отрабатывает...
 
Сначала не положила, конечно... Я ранее jar импортировала в отдельную либу)) потом положила, но все равно не работает, плюс еще при запуске клиента теперь выдается ошибка, что:

An internal error occurred during: "Getting Current Location".
java.lang.NullPointerException

А положить надо было на клиенте или на сервере? Я на своей машине положила, потому что агент на ней отрабатывает...

1. Про ошибку такую не слышал ранее.
2. Положить нужно туда, где работает скрипт.
3. Приложил бд, думаю, разберетесь.
4. Для работы с xml, xsl рекомендую xmlspy.
 

Вложения

Спасибо большое, что выложили пример, но база зашифрована((
 
Прописала java-класс еще в notes.ini, как написано в этой теме. Теперь вроде ваш код исполняется до конца, но трансформация все равно не отрабатывает - в дебаггере saxonObj пустой.

П.С. Ошибка, про которую я писала раньше, возникает, как только в %lotus%\jvm\lib\ext кладешь три jar-файла, которые находятся в архиве саксона. Я даже снесла у себя полностью лотус и поставила заново - только кладешь - сразу ошибка... не знаю, почему так.

извиняюсь.
перевыложил

СПАСИБО БОЛЬШОЕ)) сейчас посмотрю
 
Ваша база тоже не хочет у меня работать что-то... положила ваши файлики в корень с, запускаю - в статусбар мне пишет, что

LS2J Error: Threw javax.transform.TransformerFactoryConfigurationError: Provider net.sf.saxon.TransformerFactoryImpl not found.

Наверно что-то не так с импортом jar?..
 
для того чтобы выполнить пример в бд:

1) положите jar из архива, что я прикрепил сейчас в %notes%\jvm\lib\ext\
2) перегрузить лотуса
3) открыть бд "SAXON TEST"
4) выложить фалы исходник и правила из About на диск c: в корень
5) выполнить агента "SAXON TEST"

В результате должен появиться файл c:\viewXML_Result.xml

в notes.ini ничего прописывать не нужно.
 

Вложения

Теперь, когда подложила ваш jar, все стало отлично - и трансформация работает, и ошибки на клиенте исчезли)) Просто я пользовала saxon 6.5.5, т.е. тот, в котором у меня все заработало в xslt-дебагере. Где-то вычитала, что в более поздних версиях что-то не поддерживается. Но, как оказалось, это неправда :(

Еще скажите, пожалуйста, нет ли возможности брать xml и xsl не из файлов, а из NotesStream, и возвращать туда же? Просто сохранять все это в виде файлов с точки зрения нашей задачи совсем не нужно, лучше всего было бы обрабатывать в потоке и отправлять на веб-сервис в виде SOAP-запроса...
 
NotesStream - не подойдет, вернее - надо будет преобразовывать в "нормальный" стрим, потому как все, что вне Нотуса, не знает о его объектах
а так - да, файлы "совершенно не нужны" (и не только в "вашей" задаче), но только если они занимают немного места в памяти...
я неоднократно ссылался, здесь, на проект по преобразованию из РТ в ПДФ, дык вот в нём так всё и происходит
куски кода, кот. могут пригодиться:<!--shcode--><pre><code class='java'> DxlExporter exporter = session.createDxlExporter();
exporter.setForceNoteFormat(false);
exporter.setConvertNotesBitmapsToGIF(true);
exporter.setOutputDOCTYPE(false);

Stream stream = session.createStream();
System.out.println("Exported " + stream.writeText(exporter.exportDxl(doc)) +
" bytes ");
//пробразуем выходной поток во входной
ByteArrayOutputStream osxml=new ByteArrayOutputStream();
stream.getContents(osxml);
InputStream isxml=new ByteArrayInputStream(osxml.toByteArray());

//PDF generating
System.out.println("FOP ExampleXML2PDF\n");
System.out.println("Preparing...");

// Setup input and output files
View cfgview=db.getView(CFG_VIEW);
Document cfgdoc=cfgview.getDocumentByKey(XSL_NAME);
String sxslt=cfgdoc.getItemValueString("body");
ByteArrayInputStream isxslt = new ByteArrayInputStream(sxslt.getBytes());[/CODE]

Добавлено: присутствие Stream здесь необязательно и существует только для наколеночной универсальности (если надо было через файл работать) ну для примера преобразований :(
т.е. можно сразу строку (exporter.exportDxl(doc)) преобразовывать в ByteArrayInputStream
 
Imike,
спасибо большое, но для данного конкретного случая потребуется менять код явовской библиотеки, я так понимаю, потому что в экземпляр класса, определенного именно в ней, уже передаются как параметры именно пути к файлам. Т.е. ява-код берет файлики и трансформит их содержимое. На лотусскрипте я здесь ничего не исправлю((
 
ну почемуже не получится, класс кастомный, лежит в либах БД
можно добавить метод для InputStream/OutputStream
<!--shcode--><pre><code class='java'>//import java.io.File;
import java.io.*;
....
public static void TrasformFFF(InputStream sourceXML, InputStream sourceXSL, OutputStream resultXML)
throws TransformerException {
try {
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");

// Create a transform factory instance.
TransformerFactory tfactory = TransformerFactory.newInstance();

// Create a transformer for the stylesheet.
Transformer transformer =
tfactory.newTransformer(new StreamSource(sourceXSL));

// Transform the source XML to System.out.
transformer.transform(new StreamSource(sourceXML), new StreamResult(resultXML));

} catch (Exception ex) {
handleException(ex);
}
}[/CODE]почему не NotesStream :( - неполучица передавать обекты из LS
обмен через бридж возможен только на уровне стрингов, скаляров и их массивов
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!