使用 Xquery 拆分序列并递增

Splitting a sequence and incrementing using Xquery

我有一个如下所示的 xml,我正在尝试将 xml 转换为 csv

<module>
    <content>
        <catalouge SC="25" item="200">
            <Number id="250" RefIds="xyz20000">
                <Character condValue="PRE">
                    <count Number="1" Name="Sree" changeMark="1">FOR A/C 0013, 0047, 0063</count>
                </Character>
                <Character condValue="EMB">
                    <count Number="154" Name="Sree" changeMark="1">FOR A/C 0005-0010, 0021, 0025, 0033</count>
                </Character>
            </Number>
        </catalouge>
        <catalouge SC="180" item="200" >
            <Number id="780" RefIds="xyz20000">
                <Character condValue="EMB">
                    <count Number="1" Name="AB">FOR A/C 0006-0011</count>
                </Character>
                <Character condValue="EMB">
                    <count Number="154" Name="Sree" changeMark="1">FOR A/C 0013</count>
                </Character>
            </Number>
        </catalouge>
        <catalouge SC="567" item="240">
            <Number id="666" Value="123" RefIds="xyz20000">
                <Character condValue="EMB">
                    <count Number="2" Name="SB">FOR A/C 0008-0013</count>
                </Character>
                <Character condValue="PRE">
                    <count Number="1" Name="cherry" changeMark="1">FOR A/C 0018, 0047, 0063</count>
                </Character>
            </Number>
        </catalouge>
        <catalouge SC="8" item="280">
            <Number id="1994" Value="1234" RefIds="xyz20000" >
                <Character condValue="POST">
                    <count Number="3" Name="Sree" changeMark="1">FOR A/C 0006, 0047, 0063, 0090, 0143, 0172</count>
                </Character>
            </Number>
        </catalouge>
    </content>
</module>

我的xquery如下

for  $p in doc("dar.xml")//module/content/catalouge
            let $SC := $p/string(@SC)
            let $item := $p/string(@item)
            let $isns := $p/Number
            for $isn in $isns
              let $id := $isn/string(@id)
              let $Ref := $isn/string(@RefIds)              
              let $chr := (for $x in $isn return string-join($x//Character//@condValue,", "))
              let $chr_status := contains($chr, 'EMB')
              **let $count :=  $isn/Character/data(count)
              let $count_status :=  contains($chr, '0006')**
              let $Num :=  $isn/Character/count/string(@Number)
              let $sep :=";"
return (if($chr_status and $count_status) 
    then ()
  else(concat($SC,$sep,$item,$sep,$id,$sep,$Ref)) 
)

我在这里执行一个和操作,如果两个状态都为真,它应该不打印任何东西,如果它为假,它应该打印一些值。 我的输出应如下所示:

567;240;666;xyz20000
8;280;1994;xyz20000

但我的问题是,计数标记中存在的数据具有一系列值,我如何增加范围标记化这些值并搜索 0006,其中 returns 一个布尔值

<count Number="154" Name="Sree" changeMark="1">FOR A/C 0005-0012, 0021, 0025, 0033</count>

FOR A/C 0005-0012, 0021, 0025, 0033 这实际上意味着 0005 到 0012--> 我有序列 0005,0006,0007,0008, 0009,0010,0011,0012,0021, 0025, 0033

任何想法将不胜感激,谢谢!

标记逗号分隔的字符串并搜索成员,在匹配的情况下返回布尔值:

let $string := "0005,0006,0007,0008,0009,0010,0011,0012,0021,0025,0033"
return
    tokenize($string, ",") = "0006"

这个好像和你之前的问题差不多,你可以在去掉FOR A/C 前缀后使用tokenizeto运算符:

//count 
! 
(. 
|| ': ' 
|| (((
     substring-after(., 'FOR A/C ') ! 
     tokenize(., ', ') ! 
     (let $tokens := tokenize(., '-')!xs:integer(.) 
      return 
          (
              if ($tokens[2]) 
              then ($tokens[1] to $tokens[2]) 
              else $tokens[1])
          ) 
    ! format-integer(., '0001')) = '0006')))

https://xqueryfiddle.liberty-development.net/94hwpi2/2 给出

FOR A/C 0013, 0047, 0063: false
FOR A/C 0005-0010, 0021, 0025, 0033: true
FOR A/C 0006-0011: true
FOR A/C 0013: false
FOR A/C 0008-0013: false
FOR A/C 0018, 0047, 0063: false
FOR A/C 0006, 0047, 0063, 0090, 0143, 0172: true

使用这个纯 XPath 2.0 表达式:

for $text in 'FOR A/C 0005-0010, 0021, 0025, 0033'
 return
  (for $vTokens in tokenize(substring-after($text, 'FOR A/C '), '\s*,\s*')
    return
      $vTokens = '0006'
      or
       $vTokens[for $part1 in tokenize(.,'-')[1],
                    $part2 in tokenize(.,'-')[2]
                   return
                     $part1 le '0006' and $part2 ge '0006'
                ]
     )[.] and true()

它的计算结果为 true()

这是一个有多个输入的例子:

for $text in
    ('FOR A/C 0013, 0047, 0063',
     'FOR A/C 0005-0010, 0021, 0025, 0033',
     'FOR A/C 0006-0011',
     'FOR A/C 0013',
     'FOR A/C 0008-0013',
     'FOR A/C 0018, 0047, 0063',
     'FOR A/C 0006, 0047, 0063, 0090, 0143, 0172')
  return
  (for $vTokens in tokenize(substring-after($text, 'FOR A/C '), '\s*,\s*')
    return
      $vTokens = '0006'
      or
       $vTokens[for $part1 in tokenize(.,'-')[1],
                     $part2 in tokenize(.,'-')[2]
                   return
                     $part1 le '0006' and $part2 ge '0006'
                ]
     )[.] and true()

评估时,再次产生正确的结果:

false true true false false false true