2009-05-16 12 views
1

donné le code XML suivant:xslt et XPath: correspondre deux attributs noeud

<student studentID="001"> 
    <dateOfBirth> 1-1-1990 </dateOfBirth> 
    <name> Ayse Ozer </name> 
    <sex> F </sex> 
    <takes> CMPE351 </takes> 
    <takes> CMPE111 </takes> 
<takes> CMPE418 </takes> 
</student> 

<student studentID="002"> 
    <dateOfBirth> 2-2-1992 </dateOfBirth> 
    <name> Bircan Korkmaz </name> 
    <sex> F </sex> 
    <takes> CMPE418 </takes> 
    <takes> CMPE111 </takes> 
<takes> CMPE352 </takes> 
    </student> 

<course courseCode="CMPE351"> 
    <courseName> 
      Database systems I 
    </courseName> 
    <description> 
     First course in databases 
    </description>  
</course> 

<course courseCode="CMPE111"> 
    <courseName> 
      Introduction to C 
    </courseName> 
    <description> 
     First course in programming 
    </description>  
</course> 

<course courseCode="CMPE352"> 
    <courseName> 
      Database systems II 
    </courseName> 
    <description> 
     Second course in databases 
    </description>  
</course> 

<course courseCode="CMPE418"> 
    <courseName> 
      Internet Programming 
    </courseName> 
    <description> 
     Programming for the Internet. 
    </description>  
</course> 

Je veux sortie comme ça

cours suivis par les étudiants:

* Ayse Ozer 
     o CMPE351 Database systems I 
     o CMPE111 Introduction to C 
* Bircan Korkmaz 
     o CMPE418 Internet Programming 
     o CMPE111 Introduction to C 

Je w rote ce code xsl:

<xsl:template match = "school"> 
<head> 
<title>Student</title>  
</head> 
<body> 
<p>Courses Taken By Students:</p> 
    <xsl:for-each select = "student"> 
<ul> 
<li><xsl:value-of select = "name"/> </li>  
<xsl:for-each select = "takes"> 
<ul> 
<li><xsl:value-of select="text()" /> 
<xsl:value-of select = "../../course[@courseCode=text()]/courseName"/> </li> 
</ul> 
</xsl:for-each> 
</ul> 
    </xsl:for-each> 
</body> 
</xsl:template> 

<xsl:value-of select = "../../course[@courseCode=text()]/courseName"/> 
Problem about above line about text() 
+0

Dans ma réponse, j'ai supposé que/l'école est le nœud racine, avec tout le reste directement sous ... –

+0

De plus - vous seriez bien avisé d'utiliser XML standard. Cet espace supplémentaire va vous blesser, et les dates devraient suivre la disposition normale; dateOfBirth de "2-2-1992" devrait être "1992-02-02" –

Répondre

1

Le problème est les espaces blancs:

<takes> CMPE351 </takes> 

devrait être:

<takes>CMPE351</takes> 

Je vais essayer de compenser ... exemple sur le chemin ... Pour éviter beaucoup de problèmes (et améliorer les performances), je vais aussi utiliser un indice xsl ...


fixe (mise en garde - il ne fonctionnera pas avec les codes de cours avec plusieurs espaces au milieu d'entre eux, mais cela semble peu probable) :

<xsl:variable name="code" select="normalize-space()"/> 
<ul> 
    <li> 
    <xsl:value-of select="$code"/> 
    <xsl:value-of select="key('courses',$code)/courseName"/> 
    </li> 
</ul> 

avec (en haut) l'indice xsl:

<xsl:key name="courses" match="/school/course" use="@courseCode"/> 
+0

Vous avez raison les espaces de problème dans le nœud prend. Aussi j'ai changé le texte() en courant() puis cela a fonctionné correctement thx. Mais votre code fonctionne aussi avec des espaces thx beaucoup. –

0

Je travaille jusqu'à cet exemple juste avant que vous aviez déjà une bonne réponse. Puisque c'est juste une approche légèrement différente, j'ai pensé que je l'afficherais de toute façon.


<?xml version="1.0" encoding="utf-8"?> 

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="html" indent="no" encoding="UTF-8" omit-xml-declaration="yes" /> 

    <xsl:key name="courses" match="course" use="@courseCode"/> 

    <xsl:template match="school"> 
     <html> 
     <body> 
      <p>Courses taken by:</p> 
      <ul> 
      <xsl:apply-templates select="student"/> 
      </ul> 
     </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="student"> 
    <li> 
     <xsl:value-of select="name"/> 
     <ul> 
     <xsl:apply-templates select="takes"/> 
     </ul> 
    </li> 
    </xsl:template> 

    <xsl:template match="takes"> 
    <li> 
     <xsl:value-of select="."/> 
     <xsl:value-of select="key('courses', normalize-space(.))/courseName"/> 
    </li> 
    </xsl:template> 

</xsl:stylesheet> 

+0

Ce n'est pas très différent ... la même utilisation de normalize-space et xsl: key - la seule différence est l'utilisation de xsl: variable, ce qui n'est pas une différence importante. –

+0

Vrai, mais la légère différence que j'avais à l'esprit était l'utilisation originale de xsl: for-each par rapport à xsl: template ici. – Mattio

Questions connexes