[XSL] <br/>'s slopen

Pagina: 1
Acties:

  • PowerFlower
  • Registratie: Juni 2001
  • Laatst online: 15:24

PowerFlower

être diable et jouer fleur

Topicstarter
Stel dat je een brok html (paragraaf) hebt dat geconverteerd is (door Tidy) naar xml. Daarin zitten dus ook <br/>'s. Dat is op zich prima - het is heel valide dat je in een paragraaf een break wil hebben.

Wat alleen niet de bedoeling is, is dat er met meerdere <br/><br/>'s alsnog witregels binnen de paragraaf gemaakt worden (de definitie van een paragraaf is nu juist dat er een witregel na komt, niet er binnen).

Met XSL (1.0) wil ik dat er dus uitslopen. (De XSL die ik nu heb, gaat al flink met de bezem door de content heen, en laat alleen tables, lists, i en b staan, naast br). Probleem is natuurlijk: de <br/>'s zijn (lege) nodes van de paragraaf. Ik heb dan ook geen idee hoe ik uit kan vinden of er...

code:
1
2
3
4
5
<paragraaf>
  Op deze manier<br/>
  mag het<br/>
  wel
</paragraaf>


...staat, of...

code:
1
2
3
4
5
6
7
8
<paragraaf>
  op deze manier<br/>
  <br/>
  dus niet, want<br/>
  <br/>
  <br/>
  meerdere br's moeten omgevormd worden naar 1 br
</paragraaf>


...want ik heb geen idee hoe ik uit kan vinden of er tussen twee br nodes tekst staat?

Wie heeft een hint hoe ik dit aan kan pakken?

/edit: Om het nog leuker te maken, de br nodes kunnen natuurlijk ook nog children zijn van i en/of b nodes...

[ Voor 23% gewijzigd door PowerFlower op 02-03-2006 13:11 ]


  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 25-03 00:07

Jurgle

100% Compatible

Ik heb niet veel verstand van XSL. Is het een probleem om het op te lossen met regular expressions?

Je kan bijvoorbeeld een replace doen van alle:

/(<br\/>\s*<br\/>)+/

naar

<br/>

PHP heeft hiervoor preg_replace:
$nieuw = preg_replace('/(<br\/>\s*<br\/>)+/', '<br/>', $oud);

Maar voor regular expressions zit bijna in elke taal wel een extensie.

Wat je nu alleen nog niet afdekt is dat dit er niet wordt uitgefilterd:
<br/><i><br/></i><br/>

Maar dat is weer op te lossen door het pattern uit te breiden.

Succes

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


  • PowerFlower
  • Registratie: Juni 2001
  • Laatst online: 15:24

PowerFlower

être diable et jouer fleur

Topicstarter
XSL 1 heeft geen regexps. Bovendien zijn de <br>'s nodes en wordt het dus niet als string gezien (vergelijk het met de HTML DOM). Tenzij ik eerst alles in een string gooi en daar een replace op ga doen, maar dan wordt het een heel erg veel code voor een simpele taak (ook al omdat XSL 1 geen replace functie heeft, dus dat wordt ook al weer een aparte template).

Verwijderd

code:
1
following::node()[1]=following::text()[1]

following::node() geeft alle nodes (zowel child nodes als sibbling nodes) NA deze node.
following::text() geeft alle text nodes.
Kijk of de eerstvolgende node gelijk is aan de eerstvolgende tekst node, en je bent er.

  • PowerFlower
  • Registratie: Juni 2001
  • Laatst online: 15:24

PowerFlower

être diable et jouer fleur

Topicstarter
Begrijp ik het nu goed als ik zeg dat de tekst in <paragraaf> tussen de child nodes in, gezien wordt als een text node tussen de child nodes? Dan kan ik inderdaad xpath gebruiken. In mijn geval wil ik testen of de preceding node een <br> is, dus dat zou dan denk ik zijn te achterhalen met:

code:
1
name(preceding::node()[1])


...dus dat ga ik maar even in XMLSpy testen ;)

[ Voor 7% gewijzigd door PowerFlower op 02-03-2006 15:05 ]


Verwijderd

PowerFlower schreef op donderdag 02 maart 2006 @ 15:05:
Begrijp ik het nu goed als ik zeg dat de tekst in <paragraaf> tussen de child nodes in, gezien wordt als een text node tussen de child nodes? Dan kan ik inderdaad xpath gebruiken. In mijn geval wil ik testen of de preceding node een <br> is, dus dat zou dan denk ik zijn te achterhalen met:

code:
1
name(preceding::node()[1])


...dus dat ga ik maar even in XMLSpy testen ;)
Bijna. Je hebt verschillende soorten nodes. Twee daarvan zijn Text en Element. Je kijkt dus naar de volgende node, en als die gelijk is aan de eerstvolgende Text node, dan ben je er.

Dus, Text is een element uit de verzameling Nodes

--edit--
PowerFlower schreef op donderdag 02 maart 2006 @ 16:49:
Het werkt prima hoor, bedankt voor de hint die hielp me de goede kant op ;)
Graag gedaan ;)

[ Voor 15% gewijzigd door Verwijderd op 03-03-2006 10:19 ]


  • PowerFlower
  • Registratie: Juni 2001
  • Laatst online: 15:24

PowerFlower

être diable et jouer fleur

Topicstarter
Het werkt prima hoor, bedankt voor de hint die hielp me de goede kant op ;)

code:
1
2
3
4
5
<xsl:when test="name()='br' and name(preceding::node()[1])!='br'">
    <xsl:element name="br">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:when>


/edit: en die apply-templates kan er natuurlijk ook nog uit, een <br/> is altijd leeg (heb dezelfde code als basis genomen die ik voor de overige elementen gebruik) ;)

code:
1
2
3
<xsl:when test="name()='br' and name(preceding::node()[1])!='br'">
    <xsl:element name="br"/>
</xsl:when>

[ Voor 62% gewijzigd door PowerFlower op 02-03-2006 16:52 ]

Pagina: 1