【问题标题】:XQuery returning error in baseXXQuery 在 baseX 中返回错误
【发布时间】:2012-05-11 04:27:19
【问题描述】:

下面是 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>

我想列出 Chapters/Chapter/Name=Introduction 和 Chapters/Chapter/Heads/Head/No=1 以下是我在 baseX 中执行的查询 -

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

这是错误 -

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).

我做错了什么??

【问题讨论】:

    标签: xpath xquery basex


    【解决方案1】:
    /Chapters/Chapter
       [contains(Name,'Introduction') 
      and 
       contains(Heads/Head/No,'1')
       ]
         /Heads/Head/Title
    

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

    表达式的更正是

    /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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案3】:

        为了完整性和其他人处理同样的问题,只是一个后续:

        您的代码将不起作用,正如已经指出的 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)是表达您实际在做什么的简洁方式。

        【讨论】:

          【解决方案4】:

          这个可以解决问题

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-18
            • 1970-01-01
            • 2015-06-17
            • 2023-03-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多