Как проверить, что заданные значения, разделенные запятыми, имеют возрастающую числовую последовательность - PullRequest
0 голосов
/ 18 января 2019

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

Входной XML:

  <?xml version="1.0" encoding="UTF-8"?>
  <root>
     <isSequence>
        <seq name="a" value="1, 2, 3"/>
        <seq name="b" value="3, 1, 5, 6"/>
        <seq name="c" value="15, 16, 18, 0"/>
        <seq name="d" value="21, 22, 23, 24, 25"/>
        <seq name="e" value="A, B, C"/>
     </isSequence>
  </root>

Я пробовал ниже код

    <?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"
        exclude-result-prefixes="xs"
        version="2.0">
        <xsl:template match="/">
            <xsl:for-each select="root/isSequence/seq">
                <xsl:if test="subsequence(@value, 0)">
                    <xsl:value-of select="@name"/> is an ascending numeric sequence
                </xsl:if>             
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>

Ожидаемый результат

a is an ascending numeric sequence
d is an ascending numeric sequence

1 Ответ

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

Если вы ищете целочисленную последовательность, то я думаю (в XSLT 3) это можно выразить как

  <xsl:template match="seq[let $items := tokenize(@value, ',\s+')!xs:integer(.) return every $p in 1 to count($items) satisfies $items[$p] = $items[1] + ($p - 1)]">
      <xsl:value-of select="@name"/><xsl:text> is an ascending numeric sequence
</xsl:text>
  </xsl:template>

Полный пример (https://xsltfiddle.liberty -development.net / 6r5Gh2H )

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-skip"/>
  <xsl:strip-space elements="*"/>

  <xsl:output method="text"/>

  <xsl:template match="seq[let $items := tokenize(@value, ',\s+')!xs:integer(.) return every $p in 1 to count($items) satisfies $items[$p] = $items[1] + ($p - 1)]">
      <xsl:value-of select="@name"/><xsl:text> is an ascending numeric sequence
</xsl:text>
  </xsl:template>

</xsl:stylesheet>

В XSLT 2 с XPath 2 я не думаю, что вы позволили компактно выразить это в шаблоне соответствия, но вы, конечно, можете использовать переменную на уровне XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="2.0">

  <xsl:strip-space elements="*"/>

  <xsl:output method="text"/>

  <xsl:template match="seq[every $i in tokenize(@value, ',\s+') satisfies $i castable as xs:integer]">
    <xsl:variable name="items" select="for $item in tokenize(@value, ',\s+') return xs:integer($item)"/>
    <xsl:if test="every $p in 1 to count($items) satisfies $items[$p] = $items[1] + ($p - 1)">
      <xsl:value-of select="@name"/><xsl:text> is an ascending numeric sequence
</xsl:text>        
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

http://xsltransform.hikmatu.com/bFDb2BU

...