使用 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,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,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,$id,$Ref)) 
)

在这里执行 and 操作,如果两个状态都为真,则不打印任何内容,如果为假,则应打印一些值。 我的输出应该如下:

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

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

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

对于 A/C 0005-0012,0033 这实际上意味着 0005 到 0012--> 我有序列 0005,0006,0007,0008,0009,0010,00211,0033

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

解决方法

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

appendComponentToBody
,

这似乎与您之前的问题类似,您可以在删除 tokenize 前缀后使用 toFOR A/C 运算符:

//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,0063: false
FOR A/C 0006,0063,0090,0143,0172: true
,

使用这个纯 XPath 2.0 表达式

for $text in 'FOR A/C 0005-0010,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,0063','FOR A/C 0005-0010,0033','FOR A/C 0006-0011','FOR A/C 0013','FOR A/C 0008-0013','FOR A/C 0018,'FOR A/C 0006,0172')
  return
  (for $vTokens in tokenize(substring-after($text,'-')[2]
                   return
                     $part1 le '0006' and $part2 ge '0006'
                ]
     )[.] and true()

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

false true true false false false true