2016-04-28 7 views
0

Mit diesem XQuery-AusdruckWie bekomme ich alle nicht gruppierten Elemente mit distinct-values ​​() in XQuery?

for $ex in distinct-values(//products/product/@group) 
return $ex 

und diese XML

<xml> 
    <products> 
     <product id="10" group="2"></product> 
     <product id="20" group="1"></product> 
     <product id="25" group=""></product> 
     <product id="30" group="2"></product> 
     <product id="35" group=""></product> 
    </products> 
</xml> 

Ich bin immer nur:

  • Produktgruppe '2'
  • Produktgruppe '1'

Aber ich brauche auch:

  • Produktgruppe '' (@ id = 25)
  • Produktgruppe '' (@ id = 35)

Erwartet (um nicht von Interesse):

Nur 1 Produkt (das erste, wenn mehr als 1 mit der gleichen Gruppe) einer Gruppe und auch jedes Produkt ohne Gruppe.

  • Produkt-ID 10 mit der Gruppe '2'
  • Produkt-ID 20 mit der Gruppe '1'
  • Produkt-ID 35 mit der Gruppe ''
  • Produkt-ID 25 mit der Gruppe ''

Jedes Produkt mit einer leeren Gruppe sollte auch in dieser xquery zurückgegeben werden, aber wie?

+0

zu finden Was meinen Sie ... hast du nur zwei Werte (‚2‘ & ‚1‘) zurückgeführt, indem Verwenden Sie diese Abfrage, während der erwartete Rückgabewert 3 Werte ('2', '1' & '') sind? – har07

+0

@ har07 Ich erhalte 2 Produkte (mit Wert 2 und 1), aber ich brauche 4 (einschließlich der beiden Produkte, die keine Gruppe hat) – frgtv10

+0

@ har07 updatet die Frage für die Erwartung – frgtv10

Antwort

2

Auch die leere Zeichenfolge ist ein eindeutiger Wert und sollte bereits zurückgegeben werden, aber wahrscheinlich beobachten Sie es einfach nicht. Ändern Sie Ihre Anfrage an

for $ex in distinct-values(//products/product/@group) 
return <value>{ $ex }</value> 

Sie ein Ergebnis wie

<value>2</value> 
<value>1</value> 
<value/> 

erhalten (während <value/>-<value></value> gleichwertig ist und „enthält“ die leere Zeichenkette).

Wenn Sie sowohl ein einzelnes Produkt für leere Gruppen als auch alle Produkte ohne Gruppe abgleichen möchten, können Sie die Abfrage beispielsweise in zwei Teile aufteilen: Filtern nach Produkten mit Gruppen und dann Hinzufügen ohne.

(
    (: return first product for each product group :) 
    for $group in distinct-values(//products/product/@group) 
    (: unless group is empty :) 
    where $group 
    return (//product[@group eq $group])[1], 
    (: add products without any group :) 
    //product[@group eq ''] 
) 
+0

Das ist ziemlich nett, ich habe meine Frage was aktualisiert meine Ergebniserwartung sieht so aus. Vielleicht kannst du mir helfen, beide Produkte auch mit leeren Gruppen zu bekommen? – frgtv10

+0

Ich habe bereits die Bearbeitung beobachtet und die Antwort erweitert. –

+0

das ist amazin, danke für die erklärung und ihre zeit – frgtv10

1

XPath 1.0 gibt eine Möglichkeit, diese Elemente ohne Programmcode

//product[ 
    not(@group = preceding-sibling::product/@group) 
    or (@group="") 
    ] 
+0

Ohne schlaue Optimierungen führt dies zu einer quadratischen Laufzeit. Die Verwendung von "distinct-values" kann bei vernünftiger Implementierung zu linearer Laufzeit führen. Das Verwenden von XQuery 3.0-Funktionen "Gruppe nach" funktioniert möglicherweise noch schneller, wenn die Leistung wichtig ist, da die Gruppierung in kompiliertem Code implementiert ist, nicht in evaluierter XQuery. –

+0

Ich stimme dir zu. Ich halte Xpath immer für eine extreme Option, weil es sehr expansiv ist. Aber die Logik seiner Ausdrücke mag ich wirklich. Und was ist mit der Antwort - es ist nur ein anderer Ansatz zu lösen – splash58

+0

@ splash58 \t bedeutet das, dass zuerst jedes Produkt mit einer Gruppe kommt und danach jedes Produkt ohne Gruppe? wie man es bestellt, wenn wir ein Attribut namens Auftrag z. frgtv10