噩梦,有效错误:[XPTY0004]预期单项,(元素x {...},元素x {...},...)找到

时间:2012-09-18 09:57:41

标签: xml xml-parsing xquery

在我最近尝试从恶梦中访问XML数据库时,我已经非常接近了。我实际上成功了,使用了测试数据库;但是,当我将其应用到数据库时,我实际上是尝试访问,而不是BaseX示例数据库,我得到一个特殊的错误品牌,这是对XML文件的有效投诉:

通过http://basex.org/products/live-demo/

doc('test'):=

<item>
<item_number>1171270</item_number>
<seller_info>
<seller_company_id>6356</seller_company_id>
<seller_rating>C31</seller_rating>
<seller_rating>T150 hr.</seller_rating>
</seller_info>
<product_info>
<unit>2022</unit>
<sinfo>55 cases</sinfo>
<sinfo>Yu-gi-oh trading card pack</sinfo>
<sinfo>.45kg per unit</sinfo>
<sinfo>24.7500kg shipment</sinfo>
</product_info>
<product_info>
<unit>9291</unit>
<sinfo>7 units</sinfo>
<sinfo>Naruto, Classic, action figure</sinfo>
<sinfo>1.8kg per unit</sinfo>
<sinfo>12.6kg shipment</sinfo>
</product_info>
</item>

0:编写自己的查询......:=

let $doc := doc('test') 
for $v in $doc//item
where contains($v/product_info/unit,'9291')
return 
$v/seller_info/seller_company_id

返回:

Error:
Stopped at line 3, column 39: [XPTY0004] Single item expected, (element unit { ... }, element unit { ... }) found.

我不能说我没想到遇到这样的问题。不幸的是,我没有格式化XML文档 - 别人做过 - 而且它的格式非常糟糕,正如你所看到的那样。我试图访问它的部分原因是:重组它。

有没有办法运行查询我正试图在文档上运行并获得结果而不会有这个错误吐在我身上?当我尝试将Single item expected定位为返回值时,我也在查看返回时sinfo的错误,对吧?有没有办法获得,例如all of the sinfo's?或者只有the second sinfo for each product_info如果没有这个令人讨厌的错误吐了回来?

2 个答案:

答案 0 :(得分:8)

where子句中的路径$v/product_info/unit将为每个调用生成多个项目,而contains()函数仅接受单个项目作为参数。以下查询将为您提供预期结果:

let $doc := doc('test') 
for $v in $doc//item
where some $i in $v/product_info/unit satisfies contains($i,'9291')
return $v/seller_info/seller_company_id

另一个解决方案(在谓词[...]中,每个项目都将绑定到上下文项.并逐个处理):

let $doc := doc('test') 
for $v in $doc//item
where $v/product_info/unit[contains(.,'9291')]
return $v/seller_info/seller_company_id

答案 1 :(得分:2)

正如Christian所提到的,contains()xpath函数需要单个节点,但由于在xml根目录中,xpath表达式返回了两个节点。因此,XQuery可以写成

let $doc := doc('test')  
for $v in $doc//item 
where $v/product_info/unit[.='9291']
return  $v/seller_info/seller_company_id

这里要注意的另一个重要事项是使用contains()函数。如果字符串作为整体或部分字符串包含在Main字符串中,则此函数返回true。这意味着对于值为

的单位,它将返回true

9291

1 9291

23171239291 237283

...

因此建议根据需要使用正确的功能。