2016-07-10 3 views
2

Мне нужно выбрать узлы с разными значениями атрибутов имени, учитывая только первый символ.XQuery - выберите узлы с отдельной подстрокой атрибута

XML-это

<A> 
    <B name="X_01"/> 
    <B name="X_02"/> 
    <B name="Y_01"/> 
    <B name="X_03"/> 
    <B name="Z_01"/> 
    <B name="Y_02"/> 
</A> 

Желаемая выход

<B name="X_01"/> 
<B name="Y_01"/> 
<B name="Z_01"/> 

Он не должен быть первым вхождением B с отличным первым значением символа в имени атрибута.

Я новичок в XQuery и не смог построить рабочее заявление.

Спасибо за вашу помощь

ответ

2
xquery version "1.0"; 

let $xml := <A> 
<B name="X_01"/> 
<B name="X_02"/> 
<B name="Y_01"/> 
<B name="X_03"/> 
<B name="Z_01"/> 
<B name="Y_02"/> 
</A> 

let $distinct-values := fn:distinct-values(
    for $attr in $xml/B/@name 
    return fn:substring($attr,1,1) 
) 

return for $prefix in $distinct-values 
    return $xml/B[fn:starts-with(@name, $prefix)][1] 
+0

Спасибо. Работает отлично. – user3525398

+0

Не беспокойтесь. Juts помнят, что первая часть на самом деле не самая большая при масштабировании, но это, безусловно, подход, который я бы использовал, если бы знал ограничения. Для здравого смысла я просто проверил 100000 исходных XML-элементов с возможностью 1000 префиксов и все еще получил ответ на субсекунду –

+0

Хорошо для моих целей. Среднее, вероятно, около 200 элементов. – user3525398

1

Немного проще реализация с использованием группы по п таким образом:

let $stuff := <A> 
    <B name="X_01"/> 
    <B name="X_02"/> 
    <B name="Y_01"/> 
    <B name="X_03"/> 
    <B name="Z_01"/> 
    <B name="Y_02"/> 
</A> 
return 
    for $b in $stuff/B 
    group by $val := substring($b/@name, 1, 1) 
    return $b[1] 
Смежные вопросы