Регулярное выражение (last()) в XSLT
Работает над связыванием некоторого текста на входе с анализом-строкой, но не может извлечь regex-group(last())
в сценарии.
Вы можете проверить трансформацию на https://xsltfiddle.liberty-development.net/bnnZVG
Как видите, токовый выход
<?xml version="1.0" encoding="UTF-8"?>
<TEST>
<P>Check <Link ID="ID0001">AbC,2013</Link>AbC,2013Marking</P>
<P>Check <Link ID="ID0001">ABc, 2013</Link>ABc, 2013Marking</P>
<P>Check <Link ID="ID0001">ABC 2013</Link>ABC 2013Marking</P>
<P>Check <Link ID="ID0001">ABC</Link>ABCMarking</P>
<P>Check <Link ID="ID0002">BCA,2013</Link>BCA,2013Marking</P>
<P>Check <Link ID="ID0002">bcA, 2013</Link>bcA, 2013Marking</P>
<P>Check <Link ID="ID0002">BCa 2013</Link>BCa 2013Marking</P>
<P>Check <Link ID="ID0002">bcA</Link>bcAMarking</P>
</TEST>
но ожидаемый результат
<?xml version="1.0" encoding="UTF-8"?>
<TEST>
<P>Check <Link ID="ID0001">AbC,2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABc, 2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABC 2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABC</Link> Marking</P>
<P>Check <Link ID="ID0002">BCA,2013</Link> Marking</P>
<P>Check <Link ID="ID0002">bcA, 2013</Link> Marking</P>
<P>Check <Link ID="ID0002">BCa 2013</Link> Marking</P>
<P>Check <Link ID="ID0002">bcA</Link> Marking</P>
</TEST>
Заранее спасибо
1 ответ
Какую ценность вы ожидаете от звонка last()
Внутри xsl:analyze-string
? Если вы посмотрите на последний абзац в https://www.w3.org/TR/xslt-30/, он говорит:
Соответствующая подстрока обрабатывается с использованием элемента xsl: match-substring, несоответствующей подстроки с использованием элемента xsl: non-Matching substring. Каждый из этих элементов принимает конструктор последовательности в качестве своего содержимого. Если элемент отсутствует, эффект такой же, как если бы он присутствовал с пустым содержимым. При обработке каждой подстроки содержимым подстроки будет элемент контекста (как значение типа xs:string); позиция подстроки в последовательности совпадающих и несоответствующих подстрок будет позицией контекста; и количество совпадающих и несоответствующих подстрок будет размером контекста.
Таким образом last()
возвращает размер контекста, он должен быть равен количеству совпадающих и несовпадающих подстрок.
Я понимаю, что это не совсем ответ, но он слишком длинный, чтобы использовать его в качестве комментария. Вы также можете отредактировать свой вопрос и сообщить нам, чего именно должен достичь XSLT, с которым вы связались, в простых словах, и тогда мы сможем предложить подходящее решение XSLT.
Также обратите внимание, что XSLT 3 с XPath 3 имеет analyze-string
Функция, которая возвращает XML-структуру с такими совпадениями и группами, которые обрабатывают / потребляют, что может помочь вам извлечь содержимое, которое вы хотите:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="testkey" match="link" use="linkname"/>
<xsl:variable name="testcheck">
<link name="ID0001">
<linkname>abc, 2013</linkname>
<linkname>abc</linkname>
</link>
<link name="ID0002">
<linkname>bca, 2013</linkname>
<linkname>bca</linkname>
</link>
</xsl:variable>
<xsl:variable name="test">
<xsl:text>(</xsl:text>
<xsl:for-each select="$testcheck//linkname">
<xsl:if test="position() ne 1"><xsl:text>|</xsl:text></xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:text>)</xsl:text>
</xsl:variable>
<xsl:variable name="regex" as="xs:string"
select="concat('(^|\W)', replace($test, ', ([0-9][0-9][0-9][0-9])', '(, $1|,$1| $1)?'), '($|\W)')"/>
<xsl:template match="text()[matches(., $regex, 'i')]">
<xsl:apply-templates select="analyze-string(., $regex, 'i')" mode="extract"/>
</xsl:template>
<xsl:mode name="extract" on-no-match="text-only-copy"/>
<xsl:template match="fn:match/fn:group[@nr = 2]" mode="extract">
<Link ID="{$testcheck//key('testkey', lower-case(replace(current(), '(, |,| )([0-9][0-9][0-9][0-9])', ', $2')))/@name}">
<xsl:value-of select="."/>
</Link>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bnnZVG/2 дает
<TEST>
<P>Check <Link ID="ID0001">AbC,2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABc, 2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABC 2013</Link> Marking</P>
<P>Check <Link ID="ID0001">ABC</Link> Marking</P>
<P>Check <Link ID="ID0002">BCA,2013</Link> Marking</P>
<P>Check <Link ID="ID0002">bcA, 2013</Link> Marking</P>
<P>Check <Link ID="ID0002">BCa 2013</Link> Marking</P>
<P>Check <Link ID="ID0002">bcA</Link> Marking</P>
</TEST>