XQuery在baseX中返回错误

时间:2012-05-11 04:27:19

标签: xpath xquery basex

以下是XML文件 -

<Chapters>
  <Chapter>
    <Name>Introduction</Name>
    <Heads>
       <Head>
         <No>1</No>
         <Title>History of Internet</Title>
         <Desc>
         ..............
         </Desc>    
      </Head>
      <Head>
         <No>2</No>
         <Title>History of HTML</Title>
         <Desc>
         ..............
         </Desc>    
      </Head>
    </Heads>
  </Chapter>
  <Chapter>
    <Name>Learn HTML</Name>
    <Heads>
      <Head>
         <No>1</No>
         <Title>Browsers</Title>
         <Desc>
         ..............
         </Desc>    
     </Head>
     <Head>
         <No>2</No>
         <Title>Browser War</Title>
         <Desc>
         ..............
         </Desc>    
     </Head>
     <Head>
         <No>3</No>
         <Title>HTML, DHTML</Title>
         <Desc>
         ..............
         </Desc>    
      </Head>
    </Heads>
  </Chapter>
</Chapters>

我想列出章节/章节/名称=简介和章节/章节/首长/头/否= 1 以下是我在baseX中执行的查询 -

/章节/章节[包含(名称,'简介')和包含(头/头/否,'1')] /头/头/标题

这就是错误 -

Query: Chapters/Chapter[contains(Name,'Introduction') and contains(Heads/Head/No,'1')]/Heads/Head/Title

Error: [XPTY0004] Single item expected, (element No { ... }, element No { ... }) found.

根据baseX网站,错误XPTY0004的描述是 -

This error is raised if an expression has the wrong type, or cannot be cast into the specified type. It may be raised both statically (during query compilation) or dynamically (at runtime).

我做错了什么?

4 个答案:

答案 0 :(得分:4)

/Chapters/Chapter
   [contains(Name,'Introduction') 
  and 
   contains(Heads/Head/No,'1')
   ]
     /Heads/Head/Title

contains()的第一个参数必须是单个字符串,但对于上面表达式中对contains()的第二个引用,参数Heads/Head/No的计算结果为2元件。

对表达式进行修正

/Chapters/Chapter
   [Name[contains(.,'Introduction')]
  and 
   Heads/Head/No[contains(.,'1')]
   ]
     /Heads/Head/Title

备注:您似乎确实需要测试相等性 - 而不是遏制。这可以用许多方式表达,其中之一是:

/Chapters/Chapter
   [Name eq 'Introduction']
  and 
   Heads/Head/No[. eq '1']
   ]
     /Heads/Head/Title

答案 1 :(得分:2)

fn:contains($arg1 as xs:string?, $arg2 as xs:string?) as xs:boolean测试$arg2中是否包含字符串$arg1。它期望每个参数的单个字符串(或空值())。

路径步骤(此处:Heads/Head/Title)返回所有适合的元素,因此所有头部的所有标题。如果删除章节“简介”的第二个头,则查询将成功运行。

contains是这样做的错误方法。 =对集合语义进行比较。使用John的解决方案或更接近你的解决方案(但John可能会更快):

/Chapters/Chapter[Name='Introduction' and Heads/Head/No='1']/Heads/Head/Title

答案 2 :(得分:1)

这个可以解决目的

/Chapters/Chapter[Name='Introduction']/Heads/Head[No='1']/Title

但我无法回答你的问题...即我无法解释为什么你的查询导致错误!!

答案 3 :(得分:1)

为了完整性而采取后续行动,以及其他人应对同样的问题:

您的代码将无效,正如已经指出的那样contains不接受一系列字符串作为其第一个参数。

(: ssce: :)
let $doc := <doc>
            <a>
              <b>foo</b>
              <b>bar</b>
            </a>
          </doc>
return $doc/a[contains(b, "bar")]

但是有一个简单的结构可以解决这个问题。

(: ssce, this time working: :)
let $doc := <doc>
            <a>
              <b>foo</b>
              <b>bar</b>
            </a>
          </doc>
return $doc/a[some $b in b/text() satisfies contains($b, "bar")]

这些所谓的quantified expressionssome $var in exprevery $var in expr)是表达您实际行动的简明方法。