使用 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
前缀后使用tokenize
和to
运算符:
//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
我有一个如下所示的 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
前缀后使用tokenize
和to
运算符:
//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