XSLT Transforming XML into a cross referenced, nested HTML lists when source nodes are siblings and nesting is based on attribute values

StevenP

Problem: I need to create a nested HTML unordered list from XML this is not nested. Additionally I need to cross reference the XML with an 'allowed nodes' section that is also contained in the document.

Example XML:

<content>
  <data>
    <navigation>
      <link name="about us" url="#"/>
      <link name="staff" url="staff.asp" parent="about us"/>
      <link name="contact" url="contact.asp" parent="about us"/>
      <link name="facebook" url="facebook.asp"/>
    </navigation>
  </data>
  <allowedlinks>
    <link name="about us"/>       
    <link name="facebook"/>
  </allowedlinks>
</content>

Example Result HTML (note I have left out the boiler plate code):

<ul>
    <li>
      about us
      <ul>
        <li>staff</li>
        <li>contact</li>
      </ul>
    </li>
    <li>facebook</li>
</ul>

Ultimately this will form a nav menu on a site.

Rules: -I need to use XSLT 1.0 to create a solution.

-If a link exists, I need to add it to the UL and create any nested child UL's if any siblings contain a @parent of the current nodes @name.

-Before generating the LI item of any node that does not have a @parent, it must first be confirmed that its @name matches a link @name in the allowed links section.

In my opinion - the structure of the XML being transformed is really stupid and makes the transform process overly complex - however since I am unable to change the original XML, I need a solution.

Note - I do already have an answer which works okay, I will post it shortly. I wanted to see other possible answers first :)

Bonus if this can be done with template matching and not too many for each loops.

My solution contains 2 nested for-each's which I do not like.

michael.hor257k

This is a classic case for using keys:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="allowed-link" match="allowedlinks/link" use="@name" />
<xsl:key name="link-by-parent" match="link" use="@parent" />

<xsl:template match="/content">
    <ul>
        <xsl:apply-templates select="data/navigation/link[not(@parent) and key('allowed-link', @name)]"/>
    </ul>
</xsl:template>

<xsl:template match="link">
    <li>
        <xsl:value-of select="@name"/>
        <xsl:variable name="sublinks" select="key('link-by-parent', @name)" />
        <xsl:if test="$sublinks">
            <ul>
                <xsl:apply-templates select="$sublinks"/>
            </ul>
        </xsl:if>
    </li>
</xsl:template>

</xsl:stylesheet>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Transforming nested XML with XSLT

Transform XML to XML using XSLT transforming attribute values on target XML

Output is not displaying in HTML format after transforming the xml result using xslt when the attribute name contains special character

Renaming XML nodes with XSLT based on "name" attribute

XSLT 1.0 - Creating nodes based on attribute values from different nodes

Transforming attribute values into xml element

Transforming nested xml data using xslt

Group child nodes based on the values of their siblings

ArrayIndexOutOfBoundsException when transforming XML using XSLT

Empty Node Values When Transforming One Xml Document To Another using XSLT Templates

XSLT Transforming when having multiple nodes with the same name

Need help manipulating text in a <p> tag without losing children nodes when transforming xml data to html

XSLT not transforming XML

Transforming XML using an XSLT

xslt is not transforming generated xml

Query XML with nested nodes on Cross Apply

How to retrieve an xml document and group nodes based on attribute value using XSLT

XSLT 1.0: Howto merge XML nodes, then move attribute to child and change their values

XSLT transforming generic nodes to specific nodes

Transforming attribute values based on a dictionary encoded as a tree variable

Reorder XML nodes based on condition in XSLT

Transforming an XML file that contains logical operators in attribute values..?

XSLT: Colon in attribute name in source XML

Nesting lists based on the value

PHP Simple XML to get Nodes based on their attribute

Transforming xml with namespaces using XSLT

Problem transforming XML groups with XSLT

Transforming Xml using XSLT 1.0

Transforming XML to TXT using xslt