"变量尚未声明"在satisfies子句中声明的变量的错误

时间:2016-01-28 17:08:55

标签: xml xquery

我有以下代码:

let $pl := doc("playlist.xml")//Song
for $s in $pl
where some $c in $s/Comment satisfies contains($s/Comment, "LP")
return $c/Album

当我尝试运行它时,它输出一个错误: Variable $c has not been declared,我知道我应该返回$s/Album。这个错误是由于变量的范围吗?它是如何工作的?

XML文件是:

<PlaylistCollection>
  <Playlist name="Piano Jazz" numberOfEntries="2">
  <Entries>
    <Song filename="israel.mp3" songID="israel" 
     artist="bevans">
       <Title>Israel</Title>
       <Album>Explorations</Album>
       <Year>1961</Year>
       <Comment>From the original LP</Comment>
       <Genre>Jazz</Genre>
    </Song>
    <Song filename="debby.mp3" songID="debby" artist="bevans">
       <Title>Waltz For Debby</Title>
       <Album>Waltz For Debby</Album>
       <Year>1961</Year>
       <Genre>Jazz</Genre>
    </Song>
   </Entries>
  </Playlist>
  <Artist artistID="bevans" songs="israel debby">
    <FirstName>Bill</FirstName>
    <LastName>Evans</LastName>
  </Artist>
</PlaylistCollection>

在这种情况下,$c是无用的?

1 个答案:

答案 0 :(得分:2)

我通过说出名字替换了所有单个字母变量。单字母变量使得很难理解所有其他人(以及编写代码后两周)的情况,并且在解释代码的文本中引用它们也变得更加复杂。

变量声明的范围

XQuery表达式some ... in ... satisfies ...all ... in ... satisfies ...被认为以另一种方式工作。在您的情况下,$c仅绑定在satisfies子句中。而不是

where some $comment in $song/Comment satisfies contains($song/Comment, "LP")
你可以写

where some $comment in $song/Comment satisfies contains($comment, "LP")

可见性

还要重新考虑范围:where子句中的表达式是子表达式,这意味着其中的变量声明会隐藏flwor表达式的表达式,但之后不再可见对子表达式进行了评估。

隐式循环

此外,绑定in不应与let表达式进行比较,但功能更强大,可以执行隐式循环。这对于多首歌曲尤其有用。例如,如果您要做的就是测试是否存在任何包含多条评论的歌曲,您可以

some $song in $songs satisfies count($song/comment) > 1

隐式循环遍历所有$songs并测试其中一个是否满足条件。

有效布尔值

XQuery知道一个名为有效布尔值的概念。除此之外,这可以用于区分空序列和具有内容的序列。换句话说,你可以替换

where some $comment in $song/Comment satisfies contains($comment, "LP")

where $song/Comment[contains(., "LP")]

。只要有一条包含LP的注释,序列就不再为空,过滤器表达式的计算结果为true

Plain XPath 1.0对查询来说是完全足够的

最后,在这种情况下,一个简单的XPath表达式也会这样做。谓词非常强大,通常会使代码更容易阅读。

doc("playlist.xml")//Song[contains(Comment,"LP")]/Album

或者在纯文本中:在playlist.xml中,查找歌曲并过滤那些包含LP的评论。返回他们的专辑名称。