Reputation: 1780
I'd like to include a <ul>
-element within a <li>
-element, but I do not know how to do it. I tried to describe the problem in a simple and understandable way. I suspect it is only a small place, which must be adapted.
I am using XSLT 1.0.
Here is the given XML:
<University>
<Student>
<Info>Example 1.0</Info>
<Details>
<Entry>
<Info>Example 1.1</Info>
</Entry>
<Entry>
<Info>Example 1.2</Info>
</Entry>
</Details>
</Student>
<Student>
<Info>Example 2.0</Info>
</Student>
<Student>
<Info>Example 3.0</Info>
</Student>
</University>
What I want should look like this:
<div>
<p data-role="heading">UNIVERSITY</p>
<ul>
<li>Example 1.0
<ul>
<li>Example 1.1</li>
<li>Example 1.2</li>
</ul>
</li>
<li>Example 2.0</li>
<li>Example 3.0</li>
</ul>
</div>
What I get at the moment is the following code:
<div>
<p data-role="heading">UNIVERSITY</p>
<ul>
<li>Example 1.0</li>
<ul>
<li>Example 1.1</li>
<li>Example 1.2</li>
</ul>
<li>Example 2.0</li>
<li>Example 3.0</li>
</ul>
</div>
My XSLT looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nxps="urn:nxps"
exclude-result-prefixes="nxps">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- UNIVERSITY -->
<xsl:template match="University">
<div>
<!-- HEADING -->
<p data-role="heading">
<xsl:text>UNIVERSITY</xsl:text>
</p>
<ul>
<xsl:apply-templates/>
</ul>
</div>
</xsl:template>
<!-- STUDENT -->
<xsl:template match="Student">
<xsl:apply-templates/>
</xsl:template>
<!-- INFO IN STUDENT & ENTRY -->
<xsl:template match="Entry/Info | Student/Info">
<xsl:choose>
<!-- FIRST INFO -->
<xsl:when test="name(preceding-sibling::*[1])!='Info'">
<li>
<xsl:apply-templates/>
</li>
</xsl:when>
<!-- FOLLOWING INFO -->
<xsl:otherwise>
<li class="Parablock">
<xsl:apply-templates/>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- DETAILS -->
<xsl:template match="Details">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:template>
<!-- ENTRY -->
<xsl:template match="Entry">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Here is also a link to the .NET XSLT Fiddle: https://xsltfiddle.liberty-development.net/eiZQaG5/1
Upvotes: 1
Views: 91
Reputation: 70638
I think you need a template that matches Student
nodes which have a child Details
node
<xsl:template match="Student[Details]">
<xsl:apply-templates select="Info" />
</xsl:template>
Then, in your template matching Student/Info
you can select any following Details
node so that it is output as a nested element in the li
<xsl:apply-templates select="following-sibling::*[1][self::Details]" />
Try this XSLT, in which I have also simplified the Student/Info
template:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nxps="urn:nxps"
exclude-result-prefixes="nxps">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- UNIVERSITY -->
<xsl:template match="University">
<div>
<!-- HEADING -->
<p data-role="heading">
<xsl:text>UNIVERSITY</xsl:text>
</p>
<ul>
<xsl:apply-templates/>
</ul>
</div>
</xsl:template>
<!-- STUDENT -->
<xsl:template match="Student">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Student[Details]">
<xsl:apply-templates select="Info" />
</xsl:template>
<!-- INFO IN STUDENT & ENTRY -->
<xsl:template match="Entry/Info | Student/Info">
<li>
<xsl:if test="name(preceding-sibling::*[1]) = 'Info'">
<xsl:attribute name="class">Parablok</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
<xsl:apply-templates select="following-sibling::*[1][self::Details]" />
</li>
</xsl:template>
<!-- DETAILS -->
<xsl:template match="Details">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:template>
<!-- ENTRY -->
<xsl:template match="Entry">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Note you could actually remove the "Student" and "Entry" templates because XSLT's built-in templates would do exactly the same thing in this case.
Upvotes: 1