2016-03-26 22 views
1

XQuery 3.0 kullanan BaseX'i kullanıyorum.XQuery'deki XML veri kaynağını XML'ye kopyala

XQuery'deki bir XML veri kaynağını, dahil etmek istediğim tüm öğeleri yazmadan nasıl temizlerim? Böyle, her düzeyde tüm değerlerin toplamını eklemek istediğiniz

<X> 
    <name>The root</name> 
    <Y> 
    <name> Level 1</name> 
    <Z> 
     <name>Level 2a</name> 
     <value>1</value> 
    </Z> 
    </Y> 
    <Y> 
    <name>Level 1b</name> 
    <Z> 
     <name>Level 2b</name> 
     <value>2</value> 
    </Z> 
    </Y> 
</X> 

:

<X> 
    <name>The root</name> 
    <value>3</value> 
    <Y> 
    <name> Level 1</name> 
    <value>1</value> 
    <Z> 
     <name>Level 2a</name> 
     <value>1</value> 
    </Z> 
    </Y> 
    <Y> 
    <name>Level 1b</name> 
    <value>2</value> 
    <Z> 
     <name>Level 2b</name> 
     <value>2</value> 
    </Z> 
    </Y> 
</X> 

Bunun için böyle Xquery kullanabilirsiniz:

Örneğin, aşağıdaki XML dikkate
for $x in /X 
return 
<X>{ 
    $x/name, 
    <value>{sum($x//value)}</value>, 
    for $y in $x/Y 
    return 
    <Y>{ 
    $y/name, 
    <value>{sum($y//value)}</value>, 
    $y/Z 
    }</Y> 
}</X> 

Fakat bu, tekrar etmem gereken birçok öğeye sahip olduğumda çok hızlı yoruluyor. Sonuç kümesinde korumak istediğim tüm nitelikleri ve öğeleri yazmadan bu sonuca ulaşmanın bir yolu var mı?

cevap

2

Elbette yapabilirsin! XQuery oldukça güçlüdür. Daha da iyisi, BaseX sadece XQuery 3.0'ı değil, aynı zamanda XQuery Güncellemesini de destekliyor.

XQuery'nin kendisi bir sorgulama dilidir. Bu nedenle, belirli yerlere eleman eklemek istiyorsanız, örneğinizde yaptığınız gibi tüm öğeyi yeniden oluşturmanız gerekir. Bununla birlikte, XQuery Update, belgeleri güncelleştirmek için yapıları ekler, örn. Veritabanındaki değerleri güncellemek için bunu kullanabilirsiniz. Yerel olarak değeri dönüştürmek istiyorsanız, transform expression.

Belirtimde bu yapı oldukça hantal olduğundan, XML belgesini dönüştürmek için kullanabileceğiniz BaseX'e özgü update anahtar sözcüğünü kullanıma sunduk.

Yani bu sorguyu kullanarak aşağıdaki gibi görünebilir: Elbette

./X update (
    insert node <value>{sum(.//value)}</value> after ./name, 
    for $y in ./Y 
    return insert node <value>{sum($y//value)}</value> after $y/name 
) 

, senin elemanlar tekrar nasıl bağlı (bu soruya oldukça açıktır), şimdi mesela etmek için kullanabilir bu tür düğümleri uygun yerlere yinelemeli olarak yerleştirin. Bunu yapmak için bir ipucu: Eğer bir elementi dinamik olarak seçmek istiyorsanız, /X yerine /*[local-name() = 'X'] yerine yazılması zorunludur, çünkü artık eleman adı statik olmak zorunda değildir.

+2

Müthiş, bu xquery şeyi :) – wvdz

+0

ben ' yazabilirsiniz yinelemeli ekleyerek ile ifade ediyor sevmeye başladım {sum ($ şey // değer)}' kez ve yinelemeli kullanmak? Bu örnek veriler için bunun nasıl yapılacağını gösteren bir örnek ekler misiniz? Benim durumum için, birkaç seviye için yaklaşık 15 değer için toplamalar eklemem gerekiyor, bu yüzden eğer bir kere toplam kodu bir kez yazmam gerekiyorsa, bu harika olurdu. – wvdz