Подстрока XSL и indexOf

Я новичок в XSLT. Интересно, можно ли выбрать подстроку элемента. Я пытаюсь разобрать RSS-канал. Значение описания имеет больше текста, чем я хочу показать. Я бы хотел получить его подстроку на основе индекса некоторой подстроки. В принципе, я хочу показать результат вызова подстроки, передающего indxOf ('some_substring') и длину в качестве параметров. Возможно ли это?

Из комментариев:

Я хочу выбрать текст строки который находится после возникновения подстроки

Ответы

Ответ 1

Непонятно, что именно вы хотите сделать с индексом подстроки [update: теперь яснее - спасибо], но вы можете использовать функцию substring-after или substring-before:

substring-before('My name is Fred', 'Fred')

возвращает 'My name is '.

Если вам требуется более подробное управление, функция substring() может принимать два или три аргумента: string, start-index, length. Опустите длину, чтобы получить весь остаток строки.

Нет функции index-of() для строк в XPath (только для последовательностей, в XPath 2.0). Вы можете использовать string-length(substring-before($string, $substring))+1, если вам нужна определенная позиция.

Существует также contains($string, $substring). Все они описаны здесь. В XPath 2.0 вы можете использовать регулярное выражение.

(XSLT в основном использует XPath для выбора узлов и значений обработки, поэтому на самом деле это скорее вопрос XPath..)

Ответ 2

Я хочу выбрать текст строки который находится после возникновения подстроки

Вы можете использовать:

substring-after($string,$match)

Если вы хотите подстроку выше с некоторой длиной, используйте:

substring(substring-after($string,$match),1,$length)

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

substring(substring-after($string,substring-before($string,$match)),
          string-length($match) * contains($string,$match) + 1,
          $length) 

Ответ 3

Ниже приведен полный пример, содержащий как XML, так и XSLT, где используются подстрока-before и substring-after

<?xml version="1.0" encoding="UTF-8"?>
<persons name="Group_SOEM">
    <person>
        <first>Joe Smith</first>
        <last>Joe Smith</last>
        <address>123 Main St, Anycity</address>
    </person>
</persons>    

Ниже приведен XSLT, который изменяет значение первого/последнего имени, разделяя значение по пробелу, так что после применения этого XSL первый элемент имени будет иметь значение "Joe" и last "Smith".

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="first">
    <first>
        <xsl:value-of select="substring-before(.,' ')" />
    </first>
</xsl:template> 
<xsl:template match="last">
    <last>
        <xsl:value-of select="substring-after(.,' ')" />
    </last>
</xsl:template> 
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>   

Ответ 4

Вот некоторые выражения linager xpath 1.0 для IndexOf ($ text, $searchString):

Если вам нужна позиция символа FIRST искомой строки или 0, если ее нет:

contains($text,$searchString)*(1 + string-length(substring-before($text,$searchString)))

Если вам нужна позиция первого символа ПОСЛЕ найденной строки или 0, если ее нет:

contains($text,$searchString)*(1 + string-length(substring-before($text,$searchString)) + string-length($searchString))

Альтернативно, если вам нужна позиция первого символа ПОСЛЕ найденной строки или длина + 1, если ее нет:

1 + string-length($right) - string-length(substring-after($right,$searchString))

Это должно охватывать большинство случаев, которые вам нужны.

Примечание: умножение на contains (...) приводит к преобразованию истинного или ложного результата функции contains (...) в 1 или 0, что элегантно предоставляет "0, когда не найден" часть логика.

Ответ 5

В XSLT есть подстрочная функция. Пример здесь.