2012-04-09 4 views
0

Рассмотрим файл XML:XQUERY возвращает несколько значений вместо одного

Примечание: Там могут быть некоторые теги выше DEP тег или они могут отсутствовать.

Мне нужно показать список поставщиков в списке, именах товаров, которые они производят, и напротив каждого элемента название отдела, например.

Supp2 
Item1, 2 
Supp1 
Item1, 2 
Item2, 1 

Это мой код:

<ul> 
{ 
for $sup in distinct-values(doc("warehouse.xml")//supplier) 
for $item in doc("warehouse.xml")//item[supplier = $sup] 

return <li>{data($sup)} <ul> { 
let $n:= $item/itemName 
let $y:= doc("warehouse.xml")//dep[//itemName=$n]/@no 
for $n1 in $n return <li>{data($n1), data($y)} </li>} </ul> </li> 
} 
</ul> 

я столкнулся с двумя проблемами. Во-первых, что у отображает все номера отделов, начиная с 1. Другой является то, что если у меня есть 1 поставщик, который производит два элемента, вместо

Supp1 
Item1, 2 
Item2, 3 

я

Supp1 
Item1, 1,2, ... 
Supp1 
Item2, 1,2, ... 

Не могли бы вы предложить, что может быть неправым? Я глубоко благодарен.

ответ

1

Будучи новым для XQuery, я мог бы написать следующее.

Вход:

<warehouse> 
    <something/> 
    <dep no ="2"> 
    <item> 
     <itemName>Item1</itemName> 
     <supplier>Supp1</supplier> 
     <supplier>Supp2</supplier> 
    </item> 
    </dep> 
    <anything/> 
    <dep no ="1"> 
    <item> 
     <itemName>Item2</itemName> 
     <supplier>Supp1</supplier> 
     <supplier>Supp3</supplier> 
    </item> 
    </dep> 
    <whatever/> 
</warehouse> 

Запрос:

<ul>{ 
(: the ../text() can be dropped from everywhere :) 
let $doc := doc("input.xml")  
for $supplier in distinct-values($doc//supplier/text()) 
let $items := $doc//item[supplier/text() = $supplier]/itemName/text() 
return <li>{$supplier}: {string-join($items, ", ")}</li> 
}</ul> 

Выход:

<ul> 
    <li>Supp1: Item1, Item2</li> 
    <li>Supp2: Item1</li> 
    <li>Supp3: Item2</li> 
</ul> 

теория за запрос состоит в следующем.

  • Потому что вы хотите перечислить имена элементов для каждого поставщика вы в основном хотите группы поставщиков. Для этого вы должны перебрать каждый уникальный поставщик присутствующий в входе:

    distinct-values($doc//supplier/text()) 
    
  • После этого вы хотите, чтобы каждый пункт списка, связанный с данным поставщиком:

    $doc//item[supplier/text() = $supplier]/itemName/text() 
    

    , который означает, что вы захватить каждый пункт на входе, имя поставщика которого совпадает с именем данного поставщика, и вы получаете имя этих (фильтрованных) элементов.

И все. Надеюсь, я сделал какой-то смысл!

+0

Глубоко благодарен за ваш ответ. Я использую Oxygen, и кажется, что «group by» там не определен. (http://www.w3schools.com/xpath/xpath_functions.asp) Любые предложения? –

+0

@PiotrL. О, да, это очень малое количество, определенное в XQuery 3.0. Кажется, ваш процессор XQuery еще не поддерживает его. Я обновил свой ответ, чтобы он не использовал эту функцию. –

Смежные вопросы