регулярное выражение (last ()) в XSLT - PullRequest
0 голосов
/ 29 января 2019

Работает над связыванием некоторого текста на входе с помощью анализа-строки, но не может извлечь 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 Ответ

0 голосов
/ 29 января 2019

Какое значение вы ожидаете от вызова last() внутри xsl:analyze-string?Если вы посмотрите на последний абзац в https://www.w3.org/TR/xslt-30/#element-analyze-string, он говорит:

Соответствующая подстрока обрабатывается с использованием элемента 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>
...