[XPath/XSLT] XHTML-element uit XML-Node selecteren

Pagina: 1
Acties:

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
laatste probleem klik..


Ik hoop dat het antwoord heel simpel is, maar GoTSearch, GoTIrc, Google etc etc. gaven me geen goed antwoord helaas. Wat ik wil is vrij simpel, stel ik heb dit XML document

XML:
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>

<datastream>
   <objectid>Gebrabbel</objectid>
   <doccontainer>
      <p>
         Hier wat XHTML <b>data</b> bijvoorbeeld als <i>document-fragment</i><input />
      </p>
   </doccontainer>
</datastream>


Nu wil ik graag de data in de doccontainer selecteren. Ik krijg het wel voor elkaar om alleen de tekst te selecteren maar op de juiste manier met de tags eromheen wil echt niet.

Heb het o.a. al met CDATA geprobeerd (dat geeft gewoon de tags weer als tekst, niet gerendered dus)
of met allerlei xsl:value-of xpath expressies
en ook al met copy-of, wat mijn namespaces door de war gooit op de een of andere manier

Iemand die weet hoe ik dit bijvoorbeeld via value-of netjes op kan lossen?

Ook de bronnen, maar ik weet niet of iemand er wat wijs uit kan worden :X
de weergave
de xslsheet
de data

dit is het stukje uit de stylesheet waar het om gaat
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--
<block>
    <titel>etc..</titel>
    <bericht> hier de <b>xml</b></bericht>
</block>
//-->

<xsl:template name="tplCBlock">
    <h1>
        <xsl:attribute name="onclick">
            fGotoTarget(event, '<xsl:value-of select="@target" />', '<xsl:value-of select="@id" />');
        </xsl:attribute>
        <span>//</span><xsl:value-of select="titel" />
    </h1>

    <div class="stlReactie">
        <xsl:value-of select="ondertitel" />
    </div>

    <p>
        <xsl:value-of select="bericht" />   <!-- Hier gaat het dus fout! //-->
    </p>
</xsl:template>

[ Voor 46% gewijzigd door r0bert op 12-09-2005 12:04 ]


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
xsl:copy-of zou het toch moeten doen

code:
1
2
3
4
5
6
7
8
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
   <xsl:template match="/datastream">
      <hier-komt-de-output>
         <xsl:copy-of select="doccontainer/*" />
      </hier-komt-de-output>
   </xsl:template>
</xsl:stylesheet>


dat werkt toch echt gewoon.

[ Voor 186% gewijzigd door joopst op 02-09-2005 08:55 . Reden: ff verder lezen :-) ]


  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
*knip* heel verhaal

Het zat hem dus gewoon in <xsl:output method="xml" /> ipv <xsl:output method="html" /> 8)7 Thnq :)

Nu zit ik alleen nog met een ander probleem.. Hij geeft het gekopieerde element niet de default namespace (in dit geval form)
code:
1
<form xmlns="" ...>

op die manier, waardoor de rest niet correct wordt gerenderd. Enig idee wat ik hier nog aan kan doen?
zelfde bron

[ Voor 170% gewijzigd door r0bert op 02-09-2005 11:10 ]


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
kan je eens posten wat je krijgt .. en hoe je het zou willen hebben ?

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Ik krijg dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<form xmlns="" name="frmLogin" method="post" id="frmLogin">
            <table>
                <tr>
                    <td style="width: 150px;">Gebruikersnaam:</td>
                    <td><input type="text" name="txtUser" /></td>
                </tr>
                <tr>
                    <td>Wachtwoord:</td>
                    <td><input type="password" name="pwdPass" /></td>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: right;"><input type="submit" name="sbmAction" value="Login" /></td>
               </tr>
            </table>
        </form>

En wil het natuurlijk zo hebben:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     <form name="frmLogin" method="post" id="frmLogin">
            <table>
                <tr>
                    <td style="width: 150px;">Gebruikersnaam:</td>
                    <td><input type="text" name="txtUser" /></td>
                </tr>
                <tr>
                    <td>Wachtwoord:</td>
                    <td><input type="password" name="pwdPass" /></td>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: right;"><input type="submit" name="sbmAction" value="Login" /></td>
               </tr>
            </table>
        </form>
//e: note the xmlns in form. Hierdoor rendered ie niet goed. Met IE en FF kun je het verschil zien, dus dat ie 'fout' renderd in mozilla met application/xhtml+xml

//e2: zie ook hier wat ik niet wil :P
validator resultaat

[ Voor 104% gewijzigd door r0bert op 02-09-2005 12:25 ]


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
dus wat je zegt is dat het form element dat je hebt gekopieerd met xsl:copy-of is aangepast en er is een xmlns attribuut aan toegevoegd.

da's wel apart .. kan je eens laten zien hoe je dat doet ?

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Om dit te voorkomen gebruik moet je de namespace declareren als std namespace. Ik gebruik altijd dit als basis voor m'n XML -> XHTML transformaties, geen problemen in IE en FF (hoewel ik FF niet render dmv application/xhtml+xml, niet getest)
XML:
1
2
3
4
5
6
7
8
9
10
11
12
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">

 <!--
 Set the output in such a way that we can decently output XHTML
 method="xml" because we do not want the META tag and because XHTML is XML
 omit-xml-declaration because IE renders in quirksmode if it does not find a doctype as first statement
 -->
  <xsl:output indent="yes" method="xml" encoding="UTF-8" omit-xml-declaration="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>


[edit]Dan moet ik de namespace er wel bijzetten natuurlijk :D

[ Voor 43% gewijzigd door Glimi op 02-09-2005 16:07 ]


  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Ok, dit zijn mijn belangrijkste headers zoals ik ze gebruik:

voor de xmlfile
PHP:
1
2
3
4
5
6
    $sMime = (stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) ?
                      "application/xhtml+xml" : "text/html";
    header ("Content-type: ".$sMime.";charset=utf-8");
    header ("Pragma: no-cache");
    
    echo '<'.'?xml version="1.0" encoding="utf-8" standalone="no"?'.'>';


en voor de xslt file:

xsl
XML:
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" >
<xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"     
    />


de documenten worden verwerkt door middel van php:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function xmlTransform($buffer)
    {
        $xml = new DomDocument('1.0','utf-8');
        $xml->loadXML($buffer);
        
        $xsl = new DomDocument('1.0','utf-8');
        $xsl->load('./xsl/default2.xsl');

        $proc = new XSLTProcessor();

        $proc->importStyleSheet($xsl);
        
        return $proc->transformToXML($xml);
    }

//e
xsl
XML:
1
exclude-result-prefixes=""

doet de truc ook niet :'(

[ Voor 97% gewijzigd door r0bert op 05-09-2005 11:13 ]


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
Het is net wat glimi al zegt .. de standaard namespace in je xslt is gedefinieerd als:
code:
1
xmlns="http://www.w3.org/1999/xhtml"

terwijl de standaard namespace van je brondocument een 'lege' namespace heeft.

Als je je brondocument in je xslt opneemt (mbv copy-of ofzo), dan blijft de namespace van je brondocument bestaan..

Ik heb vanmorgen ff zitten pielen om te kijken of ik misschien dat brondocument van jou automagisch kon verbouwen zodat ie in de nieuwe namespace (xhtml) komt, maar dat wilde me maar niet lukken. Wellicht dat een of andere xslt god dat wel lukt B)

Wat ook een oplossing is:
code:
1
2
3
4
5
6
7
8
<datastream>
   <objectid>Gebrabbel</objectid>
   <doccontainer>
      <p xmlns="http://www.w3.org/1999/xhtml">
         Hier wat XHTML <b>data</b> bijvoorbeeld als <i>document-fragment</i><input />
      </p>
   </docco B) ntainer>
</datastream>

idd je brondocument alvast in de juiste namespace zetten.

success

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Ieder xhtml gedeelte een namespace geven is niet te doen. Ik zeg het xml/xslt wel weer gedag, want heb nu al dik een week hiermee lopen verklooien. Heel erg bedrankt voor de hulp iig en als ik het nog aan de praat krijg (hoop ik) dan post ik het nog wel.. Maar ziet er nog niet zo hoopvol uit want bovengenoemde werkt ook niet ..

  • b19a
  • Registratie: September 2002
  • Niet online
r0bert schreef op woensdag 07 september 2005 @ 00:19:
Ieder xhtml gedeelte een namespace geven is niet te doen. Ik zeg het xml/xslt wel weer gedag, want heb nu al dik een week hiermee lopen verklooien. Heel erg bedrankt voor de hulp iig en als ik het nog aan de praat krijg (hoop ik) dan post ik het nog wel.. Maar ziet er nog niet zo hoopvol uit want bovengenoemde werkt ook niet ..
Ik ben met een soortgelijks bezig, mijn tip aan jou is:

Zet je eigen tags in een namespace (bijvoorbeeld foo):
XML:
1
2
3
4
5
6
<foo:code xmlns="http://xhtml..." xmlns:foo="http://foo">
  <foo:titel>Mijn pagina</foo:titel>
  <foo:tekst>
    <p>Hier mijn <strong>data</strong></p>
  </foo:tekst>
</foo:pagina>


Je zult zien dat als je deze transformatie uitvoerd, je veel nettere XHTML zult krijgen (ik heb alleen nog een namespace in de <html>, die er dus ook hoort)!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Ok! Dat is op zich ook best netter om eigen namespace te definieren misschien. Ik ga nog even aan het puzzelen daarmee, want zou toch na al die moeite stiekem nog wel werkend willen krijgen :P Dankje :)

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
//e: heb me suf zitten zoeken waar die XMLNS naar moet verwijzen (wat voor doc, dtd?). Hoeft ie nergens naar te verwijzen 8)7 Nja iig momenteel niet echt een probleem meer

[ Voor 192% gewijzigd door r0bert op 09-09-2005 17:52 ]


  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Mijn hopelijk laatste probleem/vraag in dit topic ;)

xml
...
<my:footer>
   rechten voorbehouden <a href="./sjizzle.xml"><i>ziet</i> gij?</a><br />
</my:footer>

Nu wil ik graag de inhoud van my:footer weergeven zonder my:footer zelf.
xsl
...
<xsl:copy-of select="my:footer" />
...

selecteerd natuurlijk ook my:footer zelf, maar komt in de buurt. Heb alles al geprobeerd maar ik weet het echt niet .. iemand :?

dus
copy-of:

my:footer
my:footer/
my:footer/*
my:footer/.
my:footer//*
my:footer//.

lijken niet goed te werken :/

[ Voor 53% gewijzigd door r0bert op 12-09-2005 12:17 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Kun je dat niet met een template oplossen? Iets in deze trant:
code:
1
2
3
4
<xsl:template match="my:footer"><xsl:apply-templates /></xsl:template>
<xsl:template match="my:footer/*">
   <xsl:copy-of select="." />
</xl:template>

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Mja zoiets was ook het beste wat ik had..

xml
in my:footer
   <xsl:for-each select="*|text()">
        <xsl:call-template name="applyXHTML">
            <xsl:with-param name="node" select="." />
        </xsl:call-template>
    </xsl:for-each>

...

<xsl:template name="applyXHTML">
    <xsl:copy-of select="." />
</xsl:template>


//e

uiteindelijke versie die ik gebruikt heb:
xsl
code:
1
2
3
4
5
6
7
8
9
10
11
12
...
   <xsl:apply-templates /> <!-- Extract the descandents (?) as XHTML namespaces elements //-->
...
<xsl:template match="node()">
    <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
        <xsl:apply-templates select="@*|node()|text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*|text()">
    <xsl:copy-of select="."/>
</xsl:template>

[ Voor 68% gewijzigd door r0bert op 12-09-2005 20:07 ]

Pagina: 1