2013-12-21 2 views
1

Я часто использую этот XPath sum(preceding::*/string-length())XSLT/Xpath - выполнение функции суммы

Он делает то, что мне нужно это делать (обеспечивает подсчет символов всего текста до этого контекста в файле XML).

Проблема: она медленная.

Есть ли другая встроенная функция, которую я должен использовать вместо этого? Или расширение?

UPDATE:

Основываясь на комментарий Майкла Кея, я исследовал XSLT 3.0 <accumulator>. Это была моя первая попытка с 3.0 (мне пришлось обновить OxygenXML, чтобы он работал). Я не полностью адаптировал его к моим потребностям, но первоначальный тест ниже показывает обещание.

<xsl:output method="xml" /> 

<xsl:accumulator 
    name="f:string-summ" 
    post-descent="f:accum-string-length" 
    as="xs:integer" 
    initial-value="0"> 
    <xsl:accumulator-rule 
     match="text/*" 
     new-value="$value + string-length()"/> 
</xsl:accumulator> 

<xsl:template match="text/*"> 
     <xsl:value-of select="f:accum-string-length()" /> 
</xsl:template> 

Тема: Переполнение стека требует тега «XSLT-3.0».

+0

Какой синтаксический анализатор/компилятор Xslt вы используете? – rene

+0

Для этого ... Я использую Saxon HE, из командной строки. – Paulb

+0

Можете ли вы дать указание на размер вашего xml, текущие тайминги и целевое время? – rene

ответ

0

Если вы вызываете эту функцию на каждом узле, то производительность стилей будет равна O (n^2) в количестве узлов.

Функция в любом случае неверна. На предыдущей оси представлены предыдущие родственные братья вашего родителя, а также дети предыдущих братьев и сестер вашего родителя, поэтому длина строки ваших двоюродных братьев подсчитывается более одного раза.

Попробуйте определение функции памятки что-то вроде этого:

<xsl:function name="f:preceding-string-length" saxon:memo-function="yes"> 
    <xsl:param name="n" as="element()"/> 
    <xsl:sequence select="sum(ancestor::*/preceding-sibling::*[1]/(f:preceding-string-length(.) + string-length(.)))"/> 
</xsl:function> 

Или использовать XSLT 3.0 аккумулятор, который составляет примерно то же самое.

+0

Аккумулятор XSLT 3.0 выглядит как изящное решение. Я нашел спецификацию W3 и попробовал ее. OxygenXML с SaxonPE 9.5.0.2, появилось сообщение об ошибке «Неизвестный системный накопитель». То, что я читал, показало, что саксон должен иметь аккумулятор ... это живое? – Paulb

+0

Saxon 9.5 реализует аккумуляторы, как описано в проекте XSLT 3.0 от июля 2012 года. Проект немного изменился в проекте декабря 2013 года. –

0

Я не думаю, что функция sum медленная, перемещение по всем предыдущим элементам и вычисление длины строки всего содержимого дорого. Что касается оптимизации, какой процессор XSLT 2.0 вы используете?

+0

Для этого ... Я использую Saxon HE из командной строки. – Paulb

+0

Saxon позволяет вам профилировать таблицу стилей, см. Http://saxonica.com/documentation/html/using-xsl/performanceanalysis.html. Не помогает ли это для вашего кода. В своем комментарии к Rene вы также указываете, что ваша полная таблица стилей короткая, поэтому рассмотрите ее в своем вопросе вместе с образцом ввода, показывающим структуру, которую вам нужно обработать, а затем, возможно, кто-то еще может сделать предложение о том, как оптимизировать XSLT для саксонского языка или вообще. –

+0

Спасибо за идею Martin. Пробовал ... и он сказал мне очевидное (он сказал с бесценной мудростью заднего взгляда), что Майкл Кей поднялся ... посмотри на его ответ. Теперь я понимаю с размером некоторых моих документов: от 1 МБ до макс. 70 МБ, мне нужен подход, который выгоден для обработки потока. – Paulb

Смежные вопросы