2017-12-15 20 views
1

가장 저렴한 CD의 가격보다 적은 세 CD의 가격을 출력하는 XQuery를 만들고 싶습니다. 세 정수 매개 변수를 취하고 가장 큰 두 숫자의 합계를 생성하는 사용자 정의 함수 sumtwomax()를 작성했습니다. 이것은 숫자를 제공 할 때 작동합니다. 하지만 FLWOR 식의 변수를 제공 할 때 문제가 있습니다. 누군가가 이걸 도와 주시겠습니까? 여기변수를 숫자로 비교하는 XQuery

<items> 
    <item> 
    <code>c002</code> 
    <price>10</price> 
    <rating>5</rating> 
    </item> 
    <item> 
    <code>c006</code> 
    <price>15</price> 
    <rating>3</rating> 
    </item> 
    <item> 
    <code>c004</code> 
    <price>12</price> 
    <rating>3</rating> 
    </item> 
    <item> 
    <code>c001</code> 
    <price>7</price> 
    <rating>5</rating> 
    </item> 
    <item> 
    <code>c003</code> 
    <price>10</price> 
    <rating>4</rating> 
    </item> 
    <item> 
    <code>c005</code> 
    <price>8</price> 
    <rating>4</rating> 
    </item> 
</items> 

그리고 내 XQuery에 있습니다 : :이 대신 원하는 값 '15'로, 그 결과로 '0 0 0'을 생산

declare namespace myfn = "http://www.brookes.ac.uk/P00601/xquery/functions"; 
declare function myfn:sumtwomax($first, $sec, $third) { sum(($first, $sec, $third)) - min (($first, $sec, $third))}; 

for $d in doc("shop.xml") //item 
let $price1 := xs:integer($d/price/data()[$d/code="c002"]) 
let $price2 := xs:integer($d/price/data()[$d/code="c004"]) 
let $price3 := xs:integer($d/price/data()[$d/code="c006"]) 
return 
myfn:sumtwomax($price1, $price2, $price3) 

여기 내 XML 코드입니다. 누군가가 이걸 도와 주겠습니까? 그것은 한 번에 하나의 item 평가 (그리고 returnitem 당 하나 개의 결과를 보내고)하지만,이 경우 그 루프 내에서 실행 표현에만 유용 결과를 반환 :

+0

StackSnippets는 브라우저에서 실행할 수있는 코드 용입니다. 정규 코드 포맷팅을 위해서는'{}'를 사용하십시오. –

+0

... 그리고 btw, 컨텍스트 항목이있는 단일 문서로 작성하는 것을 고려하십시오. 사람들이 실제로 쿼리를 실행할 수 있도록 별도의'shop.xml '을 만들 필요가 없습니다. 이 질문의 코드는 단일 독립 실행 형 XQuery 인스턴스로 https://gist.github.com/charles-dyfis-net/909cb01c6affdb2149a901299f26243d를 참조하십시오. –

+0

... 그게 더 큰 문제는이 문제의 코드가 똑같은 문제를 일으키는 가장 단순한 가능한 것임을 의미합니다. 예를 들어, let $ price1 : = xs : integer ("10")'과 같은 문제를 만들 수 있다면, 그렇게해야하고,'shop.xml '을 질문에서 제외시켜야합니다. 그리고 문제를 만들 수 없다면''xs : integer ("10")'와'xs : integer ($ d/price/data() [$ d/code = "c002 "])'는 다르며 질문에'sumtwomax '를 포함 할 필요가 없습니다. –

답변

2

FLWOR 식은 이러한 맥락에서 어떤 의미가 없습니다 모두를 통해 항목을 검색하여 세 개의 변수를 모두 채울 수 있습니다 (해당 시점의 루프에 의해 반복되는 단일 항목과 관련된 변수 만이 아니라).

당신이 정말는 이것을 FLWOR 확인하려면 대신 items 이상의 요소를 (어느 하나있다) 반복 고려해 완전히 불필요한 for을 제거

declare function myfn:sumtwomax($first, $sec, $third) { sum(($first, $sec, $third)) - min (($first, $sec, $third))}; 

for $d in //items 
let $price1 := xs:integer($d/item[code="c002"]/price) 
let $price2 := xs:integer($d/item[code="c004"]/price) 
let $price3 := xs:integer($d/item[code="c006"]/price) 
return myfn:sumtwomax($price1, $price2, $price3) 

... 나 :

declare function myfn:sumtwomax($first, $sec, $third) { sum(($first, $sec, $third)) - min (($first, $sec, $third))}; 

let $price1 := xs:integer(//item[code="c002"]/price) 
let $price2 := xs:integer(//item[code="c004"]/price) 
let $price3 := xs:integer(//item[code="c006"]/price) 
return myfn:sumtwomax($price1, $price2, $price3) 
+0

답장을 보내 주셔서 감사 드리며 불필요한 텍스트를 보내 주시면 죄송합니다. xs : integer (// item [code = "c002"]/price)'가 xs : integer (// item/code/data() [// item/code = "c002" ])'? –

+1

'// item [code = "c002"]/price'는 * 모든 항목을 찾아서'code = "c002"'를 가진 사람들 만 필터링 한 다음 나머지의'price'를 취하는 것으로 생각할 수 있습니다. 반대로,''item '// item/price/data() [// item/code = "c002"]'는 * all *'item/price/data()'항목을 취하고있다. // item/code = "c002"'이 참입니다. 그러나,'// item'은 이미'price' 엘리먼트의 데이터를 선택한 특정 아이템이 아닌, 문서의 * 모든'item'을보고 있습니다. 그래서이 필터 표현식은 솔직히별로 의미가 없습니다. –