[XSLT] Eerste unieke child vanuit parent selecteren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 30-07 02:32
Ik probeer binnen een XSLT-template de eerste unieke (op basis van een aantal eigenschappen) child te selecteren om vervolgens daarmee een template in te gaan. Het probleem is echter dat ik vanuit de preceding-sibling niet weet hoe ik de waarde van de huidige child op moet vragen. Voorbeeldcode (die niet doet wat ik wil):
XML:
1
2
3
4
5
6
7
8
9
10
11
<xsl:template match="parent">
   <xsl:apply-templates select="
       child[
               not(
                     preceding-sibling::child[
                     (@att1/text() = current()/@att1/text()) and
                     (@att2/text() = current()/@att2/text())
                )
             ]
    " />
</xsl:template>

'current()' wordt in dit geval voor zover ik na kan gaan herleidt naar 'parent' ipv huidige 'child'. Misschien correct gedrag, maar niet wat ik probeer te bereiken. Ik wil kijken of de huidige 'child' de eerste unieke (@att1 en @att2) child is.

Ik gebruik de parser die standaard bij PHP wordt geleverd, dus XPath 1.0 only volgens mij.

Iemand die me een handje kan helpen?

Edit; Eigenlijk is XPath misschien meer op zijn plaats als XSLT.

[ Voor 5% gewijzigd door r0bert op 13-04-2010 20:03 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ik weet niet precies wat je nu wil, zo zonder voorbeeld en met niet-werkende code. Er ontbreekt denk ik een 'not()' ofzo. Naast "current()" en "." is er niet direct iets dat terugverwijst naar een andere node in de query die niet in een variabele zit waardoor dit gaat werken, als ik het zo snel zie. Het lijkt me het makkelijkst om gewoon even een extra xsl:if te doen, waarin current() wel goed staat. :p

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 30-07 02:32
Ik was inderdaad de not() vergeten in het voorbeeld, aangepast. In de code blijft het probleem echter bestaan.

Het voorbeeld is niet bijzonder, gewoon iets als:
XML:
1
2
3
4
5
6
7
8
9
<?xml?>
<parent>
   <child att1="aaa" att2="bbb" />*
   <child att1="bbb" att2="ccc" />*
   <child att1="bbb" att2="ccc" />
   <child att1="bbb" att2="ddd" />*
   <child att1="ccc" att2="ddd" />*
   <child att1="ddd" att2="eee" />*
</parent>

Die met een * zouden weergegeven moeten worden.

Hoe zie je de constructie met de <xsl:if /> voor je? Wat ik nu doe is alles apply-en (lijkt me eigenlijk al incorrect, want dat wil ik eigenlijk helemaal niet) en dan daar als eerst een <xsl:if /> met bovenstaande conditie en als die waar is, dan pas weergeven. Als:
XML:
1
2
3
4
5
6
7
8
9
10
11
<xsl:template match="child">
<xsl:if test=" 
               not( 
                     preceding-sibling::child[ 
                     (@att1/text() = current()/@att1/text()) and 
                     (@att2/text() = current()/@att2/text()) 
                ) 
    "> 
    <!-- Weergeven //-->
</xsl:if>
</xsl:template>


Maar die oplossing lijkt nu vast te lopen doordat ik de resultaten over verschillende pagina's moet gaan verdelen. Oftewel iets als,
XML:
1
2
3
4
5
6
7
8
9
10
<xsl:apply-templates select=" 
       child[ 
               not( 
                     preceding-sibling::child[ 
                     (@att1/text() = current()/@att1/text()) and 
                     (@att2/text() = current()/@att2/text()) 
                ) 
             ][position() &lt; 50]
    " /> 
<!-- ^ Eerste 49/50 records //-->

In een <xsl:if /> lijkt het alsof de position() niet refereert aan de positie binnen de selectie, maar gewoon van alle nodes.


Nu ik dit zit te typen begin ik trouwens wel te denken of ik de hele conditie niet in de "match" van de xsl:template kan stoppen!

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
r0bert schreef op dinsdag 13 april 2010 @ 20:15:
Hoe zie je de constructie met de <xsl:if /> voor je?
Wat je nu doet, enkel dan met kloppende (blok)haakjes, en zonder text(). ;)
Maar die oplossing lijkt nu vast te lopen doordat ik de resultaten over verschillende pagina's moet gaan verdelen. Oftewel iets als,
Als je de eerste 50 resultaten wil hebben, zou je met een variabele kunnen werken.
Nu ik dit zit te typen begin ik trouwens wel te denken of ik de hele conditie niet in de "match" van de xsl:template kan stoppen!
Helaas is er geen distinct-values beschikbaar. Wat wel kan is de "Muenchian Method", en dat is eigenlijk beter dan wat ik eerst voorstelde. :p Even zelf getest:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="childs" match="parent/child" use="concat(@att1,'-',@att2)" />
<xsl:template match="/">
   <xsl:apply-templates select="
 (parent/child[generate-id(.)=generate-id(key('childs',concat(@att1,'-',@att2)))])
 [position()&lt;=4]" />
</xsl:template>
<xsl:template match="child">
   <xsl:value-of select="concat(@att1,'-',@att2)" /><br />
</xsl:template>
</xsl:stylesheet>

Werkt prima, enkel er is zo wel een separator nodig..

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 30-07 02:32
pedorus schreef op dinsdag 13 april 2010 @ 23:36:
Wat je nu doet, enkel dan met kloppende (blok)haakjes, en zonder text(). ;)
8)7
Als je de eerste 50 resultaten wil hebben, zou je met een variabele kunnen werken.
Maar dan krijg ik een gigantische recursie (het gaat geaggregeerde feeds verwerken, dus veel items)?
Helaas is er geen distinct-values beschikbaar. Wat wel kan is de "Muenchian Method", en dat is eigenlijk beter dan wat ik eerst voorstelde. :p Even zelf getest:
(..) code (..)
Werkt prima, enkel er is zo wel een separator nodig..
Ik ga eens kijken of ik dit kan implementeren (als het iig XPath 1.0 is). Bedankt zover, ik kom er nog op terug (met het resultaat).

Acties:
  • 0 Henk 'm!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 30-07 02:32
pedorus schreef op dinsdag 13 april 2010 @ 23:36:
[..]
Helaas is er geen distinct-values beschikbaar. Wat wel kan is de "Muenchian Method", en dat is eigenlijk beter dan wat ik eerst voorstelde.
Ik heb dit prachtig werkend gekregen zoals in het voorbeeld op de gegeven URL wordt uitgelegd, top!
Pagina: 1