[XML] recursief / lagen tellen

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 14:40
Ik heb een volgende XML boom:

XML:
1
2
3
4
5
6
7
8
9
10
11
 
<categorie> 
   <item> 
     <gewicht>20</gewicht>
   <item>
   <categorie>
     <item>
       <gewicht>40</gewicht>
     </item>
   </categorie>
</categorie>


Nu wil ik graag van alle items de gewichten bij elkaar optellen. Ik weet alleen niet hoe diep de boom is, elke categorie mag weer een subcategorie met items bevatten. Ik zou het het liefste doen in een enkel statement.

Dan kom je uit op sum(/*/item/gewicht) of iets dergelijks, maar dat werkt natuurlijk maar voor 1 laag... kun je dat sterretje ook aangeven als "een of meerdere lagen"?

[ Voor 22% gewijzigd door jsiegmund op 28-02-2006 16:54 ]


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10-2025
taal?
xml stylesheet?

[ Voor 63% gewijzigd door BasieP op 28-02-2006 16:55 ]

This message was sent on 100% recyclable electrons.


Verwijderd

Gaat niet lukken met XPath ...

Edit:
I may have spoken too soon!

sum(//gewicht) zou misschien wel kunnen werken.

[ Voor 62% gewijzigd door Verwijderd op 28-02-2006 17:04 ]


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 14:40
XSL(T) inderdaad... niet mogelijk?

  • GX
  • Registratie: Augustus 2000
  • Laatst online: 14-05-2025

GX

Nee.

Lekker vies met regular expressions? Met Xpath ben je volgens mij gebonden aan diepte.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:57
Ik heb nooit zoveel gedaan met XPath, maar werkt SUM(//item/gewicht) niet gewoon?

Voor zover ik me herinner kun je met XPath (of tenminste met XQuery, wat path expressions betreft hetzelfde is) wel gewoon nodes op verschillende nivo's selecteren.

edit:
Je moet natuurlijk de nodes onder gewicht hebbem, dus dan wordt het iets van sum(//item/gewicht/child::text()).

[ Voor 74% gewijzigd door Soultaker op 28-02-2006 17:03 ]


  • PhoeniX-
  • Registratie: Juni 2000
  • Laatst online: 19-02 23:20
Kan je niet met // alle nodes selecteren die je wilt hebben? Zie http://www.w3schools.com/xpath/xpath_syntax.asp voor een voorbeeld.

  • Jaspertje
  • Registratie: September 2001
  • Laatst online: 08-04 12:54

Jaspertje

Max & Milo.. lief

Dit zou moeten kunnen werken
http://www.topxml.com/xsl/funcsum.asp

[ Voor 29% gewijzigd door Jaspertje op 28-02-2006 17:18 ]


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 14:40
Ik ga het even interessanter maken, want zo kom ik er wel uit natuurlijk 8)7

Elk item heeft ook nog een "aantal" node, en u raad het al: die wil ik vermenigvuldigen met het gewicht om tot het totale gewicht te komen. Ik kan nu met // inderdaad alles optellen, maar wil dus "het product" optellen.

Voor de duidelijkheid:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
 
<categorie> 
   <item> 
     <gewicht>20</gewicht>
     <aantal>2</aantal>
   <item>
   <categorie>
     <item>
       <gewicht>40</gewicht>
       <aantal>4</aantal>
     </item>
   </categorie>
</categorie>


Levert 2*20 + 4*40 = 200 als antwoord. Met //item krijg ik alle nodes die ik wil hebben, alleen moet ik "daarin" dus nog even dat product zien te verkrijgen.

[ Voor 44% gewijzigd door jsiegmund op 28-02-2006 17:24 ]


  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 07-04 22:27

Bosmonster

*zucht*

dus iets als getElementsByTagName('gewicht') en hetzelfde voor aantal wil je niet?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ben je niet verkeerd bezig? Zou je geen template maken die "item" matched, daar een totaal van berekent en dat recursief (of desnoods met een for-each en wat xsl-variabelen) doet? Of denk ik nou zo raar?

[ Voor 67% gewijzigd door RobIII op 28-02-2006 18:45 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Atari Paul
  • Registratie: November 2002
  • Laatst online: 17:25
Het is wat roestig allemaal, dus sorrie als hier het nodige niet aan klopt, maar volgens mij moet je het in deze richting zoeken.

code:
1
2
3
<xsl:for-each select="//item">
   <xsl:value-of select="gewicht*aantal"/>
</xsl:for-each>

Stability ?? My Atari still has it :)


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 14:40
Die laatste is leuk, maar die telt verder niets op, ik wil van al die dingen nog de som hebben. En volgens mij kun je sum() niet uitvoeren op een andere template, of zit ik dan verkeerd?

Heb het inmiddels als opgelost door in de code de totalen te bereken, viesjes maar veel handiger dan klooien in XPath. O-)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:57
Waarom voldoen de suggesties van mij, Phoenix en MrX (uiteindelijk ;)) niet dan?

  • Atari Paul
  • Registratie: November 2002
  • Laatst online: 17:25
Goed, ik kon het niet laten om uit te zoeken, hierbij een xsl oplossing in php.
Let wel, de code is niet schoon en verbeteringen moeten zeker nog worden aangebracht.
Verder is de 'Optellen' template te danken aan Doug Tidwell en werkt deze oplossing alleen in PHP5.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?
$xml_string = "<root>
                <categorie> 
                   <item> 
                     <gewicht>20</gewicht>
                     <aantal>3</aantal>
                   </item>
                   <categorie>
                     <item>
                       <gewicht>40</gewicht>
                       <aantal>4</aantal>
                     </item>
                   </categorie>
                </categorie>
                </root>";
                
$xsl_string = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' .
        '<xsl:output  method="xml" encoding="iso-8859-1" />' .
            '<xsl:template match="/">' .
                '<xsl:variable name="Totaal">' .
                    '<xsl:call-template name="Optellen">' .
                        '<xsl:with-param name="subTotaal" select="\'0\'"/>' .
                        '<xsl:with-param name="items" select="//item"/>' .
                        '<xsl:with-param name="index" select="\'1\'"/>' .
                    '</xsl:call-template>' .
                '</xsl:variable>' .
                '<xsl:value-of select="$Totaal"/>' .
            '</xsl:template>' .
            '<xsl:template name="Optellen">' .
                '<xsl:param name="items"/>' .
                '<xsl:param name="index" select="\'1\'"/>' .
                '<xsl:param name="subTotaal" select="\'0\'"/>' .
                '<xsl:variable name="currentItem">' .
                    '<xsl:value-of select="$items[$index]/gewicht*$items[$index]/aantal"/>' .
                '</xsl:variable>' .
                '<xsl:variable name="overigeItems">' .
                    '<xsl:choose>' .
                        '<xsl:when test="$index=count($items)">' .
                            '<xsl:text>0</xsl:text>' .
                        '</xsl:when>' .
                        '<xsl:otherwise>' .
                            '<xsl:call-template name="Optellen">' .
                                '<xsl:with-param name="index" select="$index+1"/>' .
                                '<xsl:with-param name="items" select="$items"/>' .
                                '<xsl:with-param name="subTotaal" select="$subTotaal+$currentItem"/>' .
                            '</xsl:call-template>' .
                        '</xsl:otherwise>' .
                    '</xsl:choose>' .
                '</xsl:variable>' .
                '<xsl:value-of select="$currentItem+$overigeItems"/>' .
            '</xsl:template>' .
        '</xsl:stylesheet>';

  $dom = new domDocument();
  $dom->loadXML($xsl_string);
  $proc = new xsltprocessor;
  $xsl = $proc->importStylesheet($dom);
  
  $document = new DomDocument();
  $document->loadXML($xml_string);
  print $proc->transformToXml($document);
?>

[ Voor 27% gewijzigd door Atari Paul op 01-03-2006 22:34 ]

Stability ?? My Atari still has it :)


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 14:40
Soultaker schreef op woensdag 01 maart 2006 @ 20:08:
Waarom voldoen de suggesties van mij, Phoenix en MrX (uiteindelijk ;)) niet dan?
Voor het originele probleem voldoen die prima, maar ik moest nog vermenigvuldigen met het aantal, en dat gaat op die manier niet.

Andere oplossing zal vast werken maar is me veel te intensief tegenover een extra attribuut waarin het product al uitgerekend is ;)
Pagina: 1