Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

XQuery attribute construction

Pagina: 1
Acties:

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17-11 16:14
Ik probeer met XQuery een XML document om te zetten naar een ander XML document. Ik heb daarin een document met elementen van de vorm <foo x="y" /> die omgezet moeten worden naar <bar x="y">. Dit werkt op zich prima met dit soort code:

XQuery:
1
2
3
4
5
let $doc := <input><foo x="aap"/><foo x="noot"/><foo x="mies"/></input>
return <output>{
    for $foo in $doc/foo
    return <bar x="{$foo/@x}" />
}</output>

De uitvoer is dan, zoals verwacht, <output><bar x="aap"/><bar x="noot"/><bar x="mies"/></output>.

Echter, soms is het attribuut "x" niet aanwezig. In dat geval wil ik eigenlijk dat het attribuut ook in de gegenereerde elementen weglaten. Bovenstaande code genereert dan echter een leeg attribuut, dus <bar x=""/> in plaats van gewoon <bar/>.

Nu heb ik daar de volgende work-around voor gevonden:

XQuery:
1
2
3
4
5
6
7
let $doc := <input><foo x="aap"/><foo/><foo x="mies"/></input>
return <output>{
    for $foo in $doc/foo
    return <bar> {
        let $x := $foo/@x where $x return <dummy x="{$x}"/>/@x
    }</bar>
}</output>

Dit genereert de gewenste uitvoer (<output><bar x="aap"/><bar/><bar x="mies"/></output>) maar het blijft een lelijke hack; niet echt duidelijk om te lezen, en misschien ook niet zo efficient (al is dat van secundair belang). De vraag is dus: is er een betere manier om dit te doen?

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Soultaker schreef op woensdag 27 augustus 2008 @ 13:37:
Ik probeer met XQuery een XML document om te zetten naar een ander XML document.
De vraag is dus: is er een betere manier om dit te doen?
Ehh, daar is XSLT voor dacht ik ipv XQuery?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17-11 16:14
XSLT vind ik onleesbaar en onschrijfbaar; leuk om transformaties te beschrijven, maar niet leuk om in te programmeren.

Maar hoe zou je dit in XSLT oplossen? V.z.i.w delen XSLT en XQuery een groot deel van de operatoren en functies, dus misschien dat er een oplossing is die in beide werkt.

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

XML:
1
2
3
4
5
6
7
8
9
10
11
<xsl:template match="/">
  <output>
    <xsl:apply-templates select="/output/foo" />
  </output>
</xsl:template>

<xsl:template match="foo">
  <bar>
    <xsl:if test="string-length(@x) &gt; 0"><xsl:attribute name="x"><xsl:value-of select="@x" /></xsl:template></xsl:if>
  </bar>
</xsl:template>


Overigens is 'een omzetting' gewoon een andere bewoording voor transformatie. En daarbij vind ik XSL niet minder leesbaar dan xquery.

If it isn't broken, fix it until it is..


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17-11 16:14
Hmm ok, ook niet heel mooi maar het principe werkt wel. (Al geeft dit het verkeerde antwoord als een attribuut wel bestaat, maar een lege string als waarde heeft; dat gaat in de XQuery versie wel goed.)

Maar nu terug naar de oorspronkelijke vraag: kan dat ook in XQuery? Zonder dummy-element te construeren?

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Die XSL kan simpeler (en zonder dat kleine probleempje):
XML:
1
2
3
4
5
6
7
8
9
<xsl:template match="/">
 <output>
  <xsl:for-each select="input/foo">
   <bar>
    <xsl:copy-of select="@x"/>
   </bar>
  </xsl:for-each>
 </output>
</xsl:template>

Die vraag over XQuery ga ik niet aan beginnen, dat is een beetje als vragen hoe je met een tang een spijker op zijn kop kan slaan... :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17-11 16:14
pedorus schreef op donderdag 28 augustus 2008 @ 17:31:
Die vraag over XQuery ga ik niet aan beginnen, dat is een beetje als vragen hoe je met een tang een spijker op zijn kop kan slaan.
Leuk, maar als iemand een vraag over Visual Basic stelt, ga ik ook niet posten dat mensen maar Java of C# moeten gebruiken. De vraag in dit topic is wat een goede manier is om attributes te constructen met XQuery.

Ik heb al aangegeven dat XQuery goed bruikbaar is voor documenttransformatie. Dat was dan ook een expliciet doel van de taal:
XML Query (XQuery) Requirements
[..]
2 Usage Scenarios
The following usage scenarios describe how XML queries may be used in various environments, and represent a wide range of activities and needs that are representative of the problem space to be addressed. They are intended to be used as design cases during the development of XML Query, and should be reviewed when critical decisions are made. These usage scenarios should also prove useful in helping non-members of the XML Query Working Group understand the intent and goals of the project.

2.1 Human-readable documents
Perform queries on structured documents and collections of documents, such as technical manuals, to retrieve individual documents, to generate tables of contents, to search for information in structures found within a document, or to generate new documents as the result of a query.

2.2 Data-oriented documents
Perform queries on the XML representation of database data, object data, or other traditional data sources to extract data from these sources, to transform data into new XML representations, or to integrate data from multiple heterogeneous data sources.

[..]

3 Requirements
[..]
3.4.11 Structural Transformation
Queries MUST be able to transform XML structures and MUST be able to create new structures.
Status: this requirement has been met.
Kortom, de W3C vind dat XQuery als transformatietaal gebruikt moet kunnen worden, en vind dat aan die eis voldaan is. Dan moet je me niet voor gek uitmaken als ik de taal daar dan ook voor gebruik. ;)

[ Voor 90% gewijzigd door Soultaker op 28-08-2008 18:25 ]


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Oei, valt mijn kennis van XQuery daar toch lelijk door de mand :) Gelukkig biedt Google denk ik uitkomst: [google=xquery copy attributes] geeft als eerste link een voorbeeld van hoe het kan, met een computed constructor. Het juiste antwoord lijkt me dus:
code:
1
element{"bar"}{$foo/@x}

Enkel ik heb niet eens iets dat XQuery doet.. (Welke implementatie gaat dit over?)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17-11 16:14
Argh, dat kan natuurlijk ook, dan heb ik die dummy node niet nodig. Raar dat ik daar niet meer aan gedacht had, want ik gebruik hetzelfde principe om de attribute van de dummy node te kopiëren.

Overigens heb je me wel geholpen door me op de expliciete constructor ("element naam {inhoud}" ) te wijzen; er is ook een soortgelijke constructor voor attributes en die is juist handig als ik de naam van de attribute ook wil kunnen wijzigen. Dat is dus de "goede" manier, wat mij betreft.

Een voordeel van XQuery is trouwens dat je meestal niet al die expliete functies nodig hebt; jouw code is equivalent aan:
XQuery:
1
element bar {$foo/@x}

wat weer equivalent is aan:
XQuery:
1
<bar>{$foo/@x}</bar>

Dus dat kan ook.
pedorus schreef op donderdag 28 augustus 2008 @ 20:35:
Enkel ik heb niet eens iets dat XQuery doet.. (Welke implementatie gaat dit over?)
Ik gebruik momenteel de gratis variant van Saxon (Saxon-B) en dat bevalt wel goed.

Voor korte tests gebruik ik meestal de online demo van X-Hive. Je kunt er een aantal standaard queries op hun demo-database doen, maar je kunt ook zelf queries geven. Voor kleine testjes is het erg handig, maar als je een query op een lokale data set wil uitvoeren moet je natuurlijk iets lokaal draaien.

Aangezien het een vrij duidelijk gedefinieerde standaard is, zou het niet uit moeten maken welke processor je gebruikt, natuurlijk. :Y)

[ Voor 17% gewijzigd door Soultaker op 28-08-2008 21:28 ]


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Wat betreft XQuery vs. XSLT is dit whitepaper van Michael Kay heel aardig.

Wie trösten wir uns, die Mörder aller Mörder?

Pagina: 1