3

以下是 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).

我做错了什么??

4

4 回答 4

4
/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
于 2012-05-11T12:42:42.470 回答
2

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

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

contains这样做是错误的。=比较一组语义。使用约翰的解决方案或更接近你的解决方案(但约翰的可能会更快):

/Chapters/Chapter[Name='Introduction' and Heads/Head/No='1']/Heads/Head/Title
于 2012-05-11T07:48:28.200 回答
2

只是为了完整性和其他人处理相同问题的后续行动:

您的代码将不起作用,正如已经指出的那样,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")]

这些所谓的量化表达式 (some $var in exprevery $var in expr) 是表达您实际在做什么的简洁方式。

于 2012-05-21T11:12:20.417 回答
1

这将解决目的

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

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

于 2012-05-11T06:23:53.800 回答